Repository navigation
fix(shell): return when the shell exits even if a background process holds its output - #194
Merged
Conversation
…holds its output A command that starts a background process without fully redirecting its output (e.g. `cd dir && setsid nohup server > log &`, where the async list's wrapper shell keeps stdout) left the shell tool waiting for the pipes to close. Because the shell itself had already exited, the timeout and the run's abort signal were no-ops too, so the Session hung indefinitely. After the shell exits, wait a short drain grace, then stop reading, return the result and tell the model that a background process still holds the output. The background process keeps running.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A Session hung for about an hour on a single
shellcall. The command started a local preview server in the background:The server redirected its own output, but bash forks a wrapper shell for the async
cd … && setsid nohup …list. That wrapper inherits the tool's stdout/stderr pipes and waits for the server. So:close, which only fires when every holder of the pipes has closed them, so the wait never ended.terminateProcessTreereturns early oncechild.exitCode !== null, andstop()then waited on the samecloseevent again.Minimal reproduction:
sleep 8 & echo readytakes 8 s instead of returning at once. With a server instead ofsleep, it never returns.Fix
Once the shell has exited, the tool waits a 500 ms drain grace for remaining output. It then destroys its stdout/stderr readers and returns the result. The result includes a notice that a background process still holds the output and how to redirect it. The background process keeps running, so intentionally started servers still work.
truncatedand the output budget now account for the notice, so the result stays inside the 4 KiB bound.Tests
Added to
shell.test.ts(written first; both failed before the fix):sleep 8 & …; echo ready→ < 3 s, output contains the notice)setsid sleep 8 & …; sleep 30, timeout 0.2 s →timedOut, < 3 s)vp checkpasses and all 291 harness tests pass. I also checked the exact command pattern from the hung Session by hand: it now returns in about 1 s, and the server keeps running.