[BUG] Background Bash's "You will be notified when it completes" is false for a subagent that stops — the copy invites orphaning, while agent children correctly resume the parent
Preflight
- [x] I have searched existing issues; the orphaning itself is reported (#23154, #19045, #72171) but not this angle: the tool copy that induces it, and the shell-task vs agent-child asymmetry
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code (2.1.218)
Summary
A subagent that starts a Bash command with run_in_background: true is shown, verbatim: "Command running in background with ID: … You will be notified when it completes." Its Bash tool description likewise says run_in_background "keeps running across turns and re-invokes you when it exits", and arming Monitor adds "Keep working — do not poll or sleep."
For the main session, all of this is true. For a subagent, none of it survives its stop: emitting final text ends the session, the backgrounded shell command dies with it, and the promised notification never arrives — there is no later turn to deliver into. Nothing in any of these messages distinguishes the two cases, so a subagent with nothing else to do follows the text as written: it backgrounds the long command and ends its turn "to wait". That is precisely obedient behavior producing an orphaned task.
The asymmetry that proves the copy is the problem: for a nested agent child the promise is honest. We verified that a subagent that stops while its own Agent-tool child is still running is kept alive and re-invoked with that child's completion notification (the notification's own footnote documents it: fires "each time this agent stops with no live background children of its own"). So the semantics are: shell background task → dies at parent stop, no notification; agent child → parent session held open and resumed. The user-facing copy claims the second behavior for both.
Reproduction
- From a top-level session, launch a
general-purposesubagent instructed to: run a ~60s marker-writing shell command withrun_in_background: true, quote the tool result it receives, then immediately output its final text "stopping to wait for the notification".
- Result: the subagent quotes "You will be notified when it completes", stops, and the marker file never completes — the process is gone. No notification ever reaches it. (Reproduced 2× today in production use before the controlled probe: two ~15-minute e2e suite runs orphaned mid-build the moment their subagent stopped "to wait".)
- Same experiment with a nested agent child instead of a shell task: subagent launches an Agent-tool child that takes ~90s, immediately stops, and carries an instruction to write a tripwire file if ever re-invoked.
- Result: ~90s later the parent is resumed by the child's completion notification and writes the tripwire. 1 trial, plus the notification footnote documenting the semantics.
- Control (what a subagent can do): foreground Bash accepts
timeoutup to 3600000ms, and anuntil <check>; do sleep 2; doneloop is permitted (only standalonesleepis blocked) — a 22s foreground await of the background task's completion marker worked inside the probe subagent.
Scope
- This is about the copy and the undocumented contract, not a request to change lifecycle mechanics (though that would also fix it — see Expected). The docs (tools-reference, sub-agents) document neither what happens to a subagent's background tasks at stop, nor the shell-vs-agent-child asymmetry.
- Distinct from #23154, which reports subagents lacking TaskStop and orphaning tasks they spawn: here the subagent is induced to orphan by text that promises re-invocation it cannot receive.
Why this matters
Capable models follow tool text literally. The stronger the model, the more reliably "You will be notified when it completes" produces a subagent that backgrounds a 30-minute job and stops — the correct reading of an incorrect promise. Each occurrence silently discards long work: our two production cases each lost a full build-and-test cycle, and the parent session read the stopped agent's final text as an interim progress report, compounding the confusion.
Expected
Any of, in preference order:
- Condition the background-Bash copy on session type: in a subagent, say the true thing — e.g. "this task will not survive your final message; await it in-session (foreground timeout, or an until-loop on its output) before handing off."
- Extend the agent-child semantics to shell tasks: hold a subagent session open while it has live background tasks and re-invoke it on completion, matching the existing behavior for Agent-tool children.
- At minimum, document the contract in sub-agents docs: background shell tasks die at subagent stop; agent children hold the session open.
Related issues
- #23154 — subagents can orphan their own Bash tasks (mechanics; no copy angle)
- #19045, #72171 — background/subagent processes orphaned at session end (adjacent lifecycle gaps)
Is this a regression?
I don't know — I haven't tested earlier versions.
Environment
- Claude Code: 2.1.218
- Model: claude-fable-5
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗