Skip to content

run_shell: return when the shell exits, keep backgrounded servers running - #140

Merged
ayman3000 merged 2 commits into
mainfrom
shell-returns-when-shell-exits
Oct 12, 2026
Merged

ayman3000 merged 2 commits into
mainfrom
shell-returns-when-shell-exits

Conversation

@ayman3000

Copy link
Copy Markdown
Owner

Bug (seen in a Naseem benchmark run): the model ran … python3 -m http.server 8080 & … in run_shell. The background server held the stdout pipe open, run_shell waited for EOF until its 120 s timeout, then killed the process group — server included — so the next chrome_devtools__new_page got ERR_CONNECTION_REFUSED.

Fix: the run ends when zsh exits, not when the pipe closes.

  • Output already written is collected (0.3 s drain). A child still holding the pipe is left running; its later output is drained and dropped, and the result says so.
  • Timeout and Stop still SIGKILL the whole process group.
  • PipeCollector reads with a dispatch readability handler and keeps the FileHandle alive until EOF (otherwise the read end closes and the server dies of SIGPIPE on its next log line — caught in the live repro).
  • Lossy UTF-8 decode so the byte cap can't blank output; python3 -m http.server added to the auto-background markers.

Tests

  • Replaced shellTimesOutEvenWhenOrphanHoldsStdout (it asserted the old behavior) with shellReturnsWhenShellExitsAndLeavesBackgroundChildRunning — failed before the fix (21 s, killed child), passes after (<1 s, child alive).
  • shellTimeoutKillsTheWholeGroup, shellDetectsPython3HTTPServer.
  • Live repro (not committed): python3 -m http.server 8799 & sleep 1; echo up returns in 1.5 s and three later curls get the page.
  • Full suite: 665 tests pass (1 pre-existing known issue).

🤖 Generated with Claude Code

ayman3000 and others added 2 commits October 12, 2026 05:16
…ning

A command that backgrounds a server itself (`python3 -m http.server 8080 &`)
left a child holding the stdout pipe, and run_shell waited for that pipe to
close: the agent sat out the full timeout (120 s default), then the group
kill took the server down, so the next browser call got
ERR_CONNECTION_REFUSED.

The run now ends when zsh exits. Output already written is collected
(short drain); a child still holding the pipe is left running, its later
output drained and dropped, and the result says so. Timeout and Stop still
kill the whole group.

- PipeCollector reads via a dispatch readability handler and holds the
  handle until EOF (a deallocated handle closed the read end and the
  server died of SIGPIPE on its next log line).
- Lossy UTF-8 decode, so a byte cap can't blank the output.
- `python3 -m http.server` joins the auto-background markers.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@ayman3000
ayman3000 merged commit 9ca47d6 into main Oct 12, 2026
1 of 2 checks passed
@ayman3000
ayman3000 deleted the shell-returns-when-shell-exits branch October 12, 2026 03:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant