Background Bash completion wake owed to a stopped subagent is enqueued then removed undelivered — subagent never re-invoked, parent waits forever
Bug Description
When a subagent (Task/Agent tool) starts a long Bash command that the harness auto-backgrounds, and the subagent then ends its turn to wait for the completion notification, the background task's completion wake is enqueued into the parent session's notification queue, skipped while later-enqueued items are delivered past it, and eventually removed undelivered. The stopped subagent is never re-invoked, even though the harness promised "You will be notified when it completes" and the background task finished successfully (exit code 0, output fully written).
Net effect: the parent (lead) session waits indefinitely on a subagent that is parked on work that silently finished. The operator sees no running agents (accurate — nothing is running), and the work product sits complete on disk.
Related but distinct from #20754 (parallel agent completions racing): here it is a nested background Bash wake owed to a stopped subagent, single task, no simultaneous completions — and the session's queue-operation log shows the notification explicitly enqueued and later removed without delivery.
Environment
- Claude Code Version: 2.1.207
- OS: Windows 11 Pro 10.0.26200
- Shell: PowerShell primary; Git Bash for Bash tool
Steps to Reproduce
- Launch a subagent (Task tool) whose work includes a long-running Bash command (several minutes).
- The Bash call exceeds the foreground window and is auto-backgrounded by the harness ("You will be notified when it completes"), OR the subagent uses
run_in_backgroundexplicitly. - The subagent ends its turn to wait for the notification (its attempt to
sleep-poll may be blocked by policy, encouraging exactly this wait). - The background command completes successfully.
Expected Behavior
The completion wake re-invokes the stopped subagent (or at minimum is delivered to the parent session), so the subagent can read the output and report.
Actual Behavior (two verified instances, timestamps from session queue-operation logs)
Instance 1: subagent's background task completed 03:38:39Z with exit 0 and full output written. Queue log: enqueue at 03:38:39.7Z → a later-enqueued unrelated notification was delivered at 03:41:32Z → the pending wake was removed undelivered at 04:03:13Z. Zero SubagentStop hook events for the subagent after its park; it was never re-invoked. A manual SendMessage nudge at 04:02:59Z recovered it instantly (it read the finished output in one call).
Instance 2: subagent parked awaiting a self-created background timer ("wait 15 min"). Timer completed exit 0; the enqueue of its notification is the final line of the parent session transcript — no dequeue, no further turn, chain permanently stalled until manually nudged.
Aggravating factors
- When the subagent parks (stops its turn with a live background child), the parent receives a
<task-notification>withstatus: completedfor the subagent — while the subagent's output file is 0 bytes.completedis misleading for a parked-awaiting-its-own-background-task agent; the parent can only infer "parked" from prose. - Agents resumed via a message ("had no active task; resumed from transcript in the background") create no new task registration, so parked/resumed subagents are invisible in the background-tasks list — users see "no agents running" while a lead is legitimately holding for one.
Workaround
A manual message to the parked subagent ("status check: read your background task's output and report") reliably recovers it — verified in both instances.