[BUG] Auto-backgrounded Bash command survives SIGTERM of claude -p (2.1.300, Linux) and runs on as an orphan
What happened
When the CLI receives SIGTERM, a Bash command that it moved to the background outlives the CLI. The command keeps running as an orphan, with nothing left to stop it.
Setup: Claude Code 2.1.300 on Linux, headless. An orchestrator spawns claude --print --output-format stream-json --verbose --dangerously-skip-permissions in its own process group. The orchestrator is Paperclip's claude_local adapter.
Sequence observed on 2026-10-15:
- The model ran a Bash command without a
timeoutparameter:find / -name <file> 2>/dev/null | head. - After 120 s the tool result was: "Command did not complete within its 120s timeout and was moved to the background (ID: …). … If it is still running after 10m in the background, it will be stopped and you will be notified."
- The model ended its turn, and the CLI emitted the terminal
resultevent (subtype: "success",is_error: false). - With a background task still running, the CLI did not exit. The orchestrator sent SIGTERM to the CLI's process group. The CLI exited with code 143.
- The backgrounded command was not stopped. Its
bash -cwas reparented tosystemd --user, in its own process group (pgid = its own pid). Thefind(bfs) went on walking a network mount for 1 h 47 min, until I killed it. The "stopped after 10m in the background" never happened, because the CLI that would have stopped it was gone.
A second session the same day left a bfs / … | xargs grep … | ugrep … pipeline running the same way, for 4 h 17 min.
Expected
When the CLI exits, SIGTERM included, the background tasks it started are stopped. The docs say so in two places:
- headless: "On SIGTERM, Claude Code terminates the process tree of any Bash command that is still running";
- interactive mode: "Background tasks are automatically cleaned up when Claude Code exits".
Two changelog entries look like the same class of bug:
- 2.1.212: "Fixed SIGTERM during a running Bash tool orphaning the command's process tree in print/SDK mode";
- 2.1.257: "Fixed background commands that detach from their shell (for example under
timeoutorsetsid) surviving a task stop or Claude Code exit".
Here the command had been auto-backgrounded by the CLI itself, and the exit was SIGTERM in print mode.
Notes
- The background shell gets its own process group, so an orchestrator that kills the CLI's process group cannot reach it. Only the CLI knows these tasks exist.
- Workaround:
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1, with which a timed-out command stops instead. One agent configured this way had 0 runs ending in exit 143 out of 361 over 7 days. Four agents without it had 18 out of 858. - Related orchestrator issue: paperclipai/paperclip#14611 (exit 143 after a successful result, caused by the leftover background task).
- What I did not verify: I have not reproduced this outside the orchestrator. The evidence comes from the production processes: their
/procentries showed PPIDsystemd --user, and the run that started them had ended about 1 h 40 min earlier.