fix: add default timeout for terminal command tool execution#10550
fix: add default timeout for terminal command tool execution#10550RomneyDa merged 2 commits intocontinuedev:mainfrom
Conversation
|
All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
There was a problem hiding this comment.
3 issues found across 2 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="core/tools/implementations/runTerminalCommand.ts">
<violation number="1" location="core/tools/implementations/runTerminalCommand.ts:179">
P3: Non-streaming waitForCompletion schedules timeout/sigkill timers but the error handler does not clear them, leaving timers to fire after rejection and potentially kill/mutate output for a failed spawn.</violation>
<violation number="2" location="core/tools/implementations/runTerminalCommand.ts:180">
P2: SIGKILL fallback never runs because childProc.killed becomes true immediately after SIGTERM; it does not indicate process exit. Use exitCode/signalCode to detect whether the process is still running.</violation>
</file>
<file name="core/tools/implementations/runTerminalCommand.timeout.vitest.ts">
<violation number="1" location="core/tools/implementations/runTerminalCommand.timeout.vitest.ts:35">
P2: Extra closing brace ends the describe block before the final test, leaving the last test outside the setup/teardown and out of scope for helpers/mocks.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
|
I have read the CLA Document and I hereby sign the CLA |
|
recheck |
e585e06 to
03595e5
Compare
|
I have read the CLA Document and I hereby sign the CLA |
Terminal commands with waitForCompletion=true had no timeout, risking indefinite hangs. Adds a 2-minute default timeout with graceful SIGTERM -> 5s grace period -> SIGKILL escalation. Both streaming and non-streaming code paths are covered. The SIGKILL timer is properly cleared if the process exits during the grace period.
03595e5 to
ce37e50
Compare
|
@sestinj CI is fully green (including both required checks), and this is a small, self-contained safety improvement (default 2-min timeout + proper SIGKILL timer cleanup, tests included). Would appreciate a quick review when you have a moment. Thanks! |
|
There's a good piece of feedback on here from cubic, but otherwise I'd say this looks good if you can address that! |
|
Thanks for the review! I’ll address cubic’s feedback and push an update shortly. |
|
Thanks for the review — I've addressed cubic's feedback and pushed an update. Changes made:
These changes were applied consistently to both streaming and non-streaming paths. @cubic-dev-ai could you please re-run the review? |
@amabito I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
2 issues found across 2 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="core/tools/implementations/runTerminalCommand.ts">
<violation number="1" location="core/tools/implementations/runTerminalCommand.ts:180">
P2: SIGKILL escalation never runs after SIGTERM because `childProc.killed` becomes true as soon as SIGTERM is sent, even if the process is still running. The timeout can leave hung processes running indefinitely.</violation>
<violation number="2" location="core/tools/implementations/runTerminalCommand.ts:200">
P2: Timeout-killed processes are reported as completed because the close handler treats `code === null` (signal termination) as success; after sending SIGTERM/SIGKILL on timeout, the final status will misleadingly be “Command completed.”</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Replace `childProc.killed` with `exitCode === null && signalCode === null` for accurate process-state detection, and clear sigkillTimeoutId in error handlers to prevent delayed kills after rejection. Applied to both streaming and non-streaming paths.
|
@cubic-dev-ai Thanks for the review! I've addressed both points: 1. Replaced Added an 2. Clear Both the streaming and non-streaming Tests updated to set |
|
It looks like the win32 build-and-upload-vsix job is failing. From a quick scan, I don't see any Windows-specific paths touched in this PR, but I may be missing something. Happy to dig into the raw logs or try to reproduce locally if that helps narrow it down. |
|
Any update on this? Happy to rebase if needed. |
Summary
runTerminalCommandcould hang indefinitely, blocking the entire sessionChanges
core/tools/implementations/runTerminalCommand.ts— timeout logic for both streaming and non-streaming modescore/tools/implementations/runTerminalCommand.timeout.vitest.ts— 5 test cases covering timeout, cleanup, and background process exclusionDetails
DEFAULT_TOOL_TIMEOUT_MS = 120_000(2 minutes)waitForCompletion=false(background) processes are not affected[Timeout: process killed after 2 minutes]Test plan
runTerminalCommand.timeout.vitest.tspassesrunTerminalCommand.vitest.tsunaffected🤖 Generated with Claude Code
Continue Tasks: ✅ 1 no changes — View all
Summary by cubic
Add a default 2-minute timeout to runTerminalCommand to prevent hung commands from blocking sessions. Uses graceful SIGTERM → SIGKILL shutdown with accurate process-state checks and full timer cleanup.
Written for commit 8a01aac. Summary will update on new commits.