Headless -p session exits when a turn ends while a background task is the only pending wake signal
Environment
- Claude Code 2.1.228 and 2.1.232 (reproduced on both), Linux x86_64
- Non-interactive:
claude -p "<prompt>" --output-format stream-json --verbose, launched detached (nohup … &, stdin/dev/null)
Bug
In a headless -p session, if the model ends its turn while a harness background task (a Bash call with run_in_background, or a background subagent) is still running and is the session's only pending wake source, the process exits at end of turn instead of staying alive and re-invoking the model when the task notification arrives. In interactive mode the same situation re-wakes the conversation normally.
Measured twice in one day (2026-08-13), same signature both times in the stream-json tail:
- the last assistant text is a mid-work status message (the model clearly intended to continue after the background task finished — no final answer/result marker it had been instructed to emit),
- followed by trailing background-task lifecycle events,
- then process exit with a result object.
Consequences: any OS child processes the session was tracking are orphaned, and the session's final wrap-up work never happens — the session is lost mid-flight rather than completing.
Expected
Either (a) a -p session with pending tracked background tasks stays alive and delivers the completion notification as a new turn, matching interactive behavior, or (b) the end-of-turn/exit contract for print mode with pending background tasks is documented so harness authors know a turn must never end while a background task is the only wake signal.
Workaround we use
Launch long-running children as detached OS processes and hold a synchronous foreground wait loop inside a single turn (poll pid liveness + output-file mtime, sleep inside the loop); never end a turn with a pending harness background task. This works but forfeits background-task ergonomics in exactly the sessions that need them most.