Skip to content

fix(spawn): stop subprocess agents from blocking on unread pipes#54

Merged
tjb-tech merged 1 commit intoHKUDS:mainfrom
who96:codex/fix-subprocess-drain-pipe
Mar 22, 2026
Merged

fix(spawn): stop subprocess agents from blocking on unread pipes#54
tjb-tech merged 1 commit intoHKUDS:mainfrom
who96:codex/fix-subprocess-drain-pipe

Conversation

@who96
Copy link
Copy Markdown
Contributor

@who96 who96 commented Mar 21, 2026

Summary

SubprocessBackend.spawn() launched long-lived agent processes with both stdout and stderr set to subprocess.PIPE, but nothing ever drained those pipes. A noisy child process could eventually block once the OS pipe buffer filled up.

What changed

  • stdout now goes to subprocess.DEVNULL
  • stderr now goes to subprocess.DEVNULL
  • the existing shell on-exit lifecycle hook stays in place
  • registry writes still record the spawned subprocess as before

Why this approach

There are two obvious fixes here: drain the pipes in the background, or stop creating unread pipes in the first place.

For this backend, the simpler choice is better. These subprocess agents are not managed as interactive streams, and the backend was never surfacing their output to callers. Redirecting to DEVNULL removes the hang risk without adding thread or process management.

Compatibility / Security impact

  • tmux behavior is unchanged
  • transport behavior is unchanged
  • registry writes are unchanged
  • lifecycle on-exit behavior is unchanged
  • child stdout/stderr is now discarded instead of buffered

Test plan

  • Ran uv run pytest -q tests/test_spawn_backends.py -k discards_output_and_preserves_exit_hook_and_registry
  • Ran uv run pytest -q tests/test_spawn_backends.py
  • Ran uv run python -m pytest -q
  • Verified subprocess spawns no longer use unread pipes
  • Verified the lifecycle hook is still appended to the shell command
  • Verified register_agent(...) still receives the expected subprocess payload

Evidence / Actual results

  • uv run pytest -q tests/test_spawn_backends.py -k discards_output_and_preserves_exit_hook_and_registry
    • 1 passed, 24 deselected in 0.07s
  • uv run pytest -q tests/test_spawn_backends.py
    • 25 passed in 10.33s
  • uv run python -m pytest -q
    • 319 passed in 13.06s

Human verification

  • subprocess agents no longer create unread PIPEs that can fill and block
  • the branch keeps the existing lifecycle and registry contract intact

Risks / rollback

  • child output is now discarded instead of buffered
  • if we later want retained subprocess logs, that should be a separate feature with explicit log handling instead of hidden unread pipes
  • rollback: revert the branch commit

@tjb-tech tjb-tech merged commit 1cb0bb1 into HKUDS:main Mar 22, 2026
7 checks passed
a24ibrah pushed a commit to a24ibrah/ClawTeam that referenced this pull request Mar 30, 2026
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.

2 participants