From 07c6fd7893d959cd6b1df1f40f665f18bd0ded19 Mon Sep 17 00:00:00 2001 From: Quratulain-bilal Date: Tue, 4 Aug 2026 01:06:01 +0500 Subject: [PATCH] fix: add timeout to streaming subprocess.run() in base.py dispatch_command The streaming branch of dispatch_command() called subprocess.run() without a timeout, which could hang indefinitely if the child process stalls. Now uses the same timeout parameter (default 600s) as the non-streaming branch, with proper TimeoutExpired handling. --- src/specify_cli/integrations/base.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/specify_cli/integrations/base.py b/src/specify_cli/integrations/base.py index cca4f13976..98045c6c6c 100644 --- a/src/specify_cli/integrations/base.py +++ b/src/specify_cli/integrations/base.py @@ -386,15 +386,22 @@ def dispatch_command( cwd = str(project_root) if project_root else None if stream: - # No timeout when streaming — the user sees live output and - # can Ctrl+C at any time. The timeout parameter is only - # applied in the captured (non-streaming) branch below. + # Stream output directly to the terminal so the user sees live + # progress. Apply the same timeout as the captured branch to + # prevent indefinite hangs if the child process stalls. try: result = subprocess.run( exec_args, text=True, cwd=cwd, + timeout=timeout, ) + except subprocess.TimeoutExpired: + return { + "exit_code": 124, + "stdout": "", + "stderr": f"Command timed out after {timeout}s", + } except KeyboardInterrupt: return { "exit_code": 130,