Background Bash task completion never resumes in-process subagents — they idle forever while finished work sits on disk
Summary
When a subagent spawned via the Agent tool (an in-process teammate / named background agent) starts a Bash tool call with run_in_background: true and then ends its turn to wait, the background task's completion never re-invokes that subagent. The main session gets background-task completion notifications; in-process subagents do not. The subagent sits idle (idleReason: "available") forever while its finished work sits unread on disk.
Repro shape
- Main session spawns a named agent via the Agent tool.
- That agent runs Bash with
{command: "<long-running command>", run_in_background: true}. - The agent ends its turn, expecting to be woken on completion (the Bash tool description tells the main loop it will be re-invoked when a background task exits).
- The background command completes minutes later — the task
.outputfile is written, the process exits cleanly. - The agent is never resumed. An inbound
SendMessagefrom the parent does resume it (the wake path itself works), but no wake ever fires on task completion.
Evidence
Two independent occurrences on 2026-07-18, Claude Code 2.1.214, macOS (Darwin 25.5.0), same shape, different agents:
- Agent A: launched a background Bash task at 01:38Z, sent one status message at 01:39Z, idle since. The background command completed ~01:56Z (harness task
.outputfile under/private/tmp/claude-<uid>/…/tasks/frozen at completion; the command's on-disk results fully written). No resume ever fired; the subagent transcript simply ends after the status message. - Agent B: same pattern at 01:53Z — this agent even backgrounded a pure blocking wait command specifically to be woken on completion. The command completed ~02:10Z. No resume.
In both subagent transcripts the last event is a clean text turn; the parent transcript shows only idle_notification from each agent afterward. Full transcripts available on request.
Expected
Either background task completion re-invokes the owning subagent (as it does the main session), or the harness should make the asymmetry explicit — e.g., reject/warn on run_in_background in subagent context — so agents don't silently deadlock on a notification that structurally cannot arrive.
Impact
Any delegation pattern where a subagent backgrounds a long command and waits deadlocks silently: the work completes, the results sit on disk, and the agent never reports. This presents to the operator as "my agents are frozen" even though nothing is running or stuck. (Related in spirit to #75559 — subagent context/tool-surface gaps.)
Showing cached comments. Read the full discussion on GitHub ↗
4 Comments
This is a significant gap for any orchestration pattern where agents are expected to self-drive after completing background work -- essentially every "fire and forget, check in when done" workflow breaks silently here.
The asymmetry you describe (parent gets completion notifications, in-process subagents do not) suggests the wake-on-completion path is only wired to the main session's event loop and not to the per-agent event loop. Which means the problem isn't the wake mechanism itself -- it works for the parent -- it's that named agents don't get a copy of the notification.
A visible symptom worth checking: does the subagent's idleReason stay as "available" even after the background task file is written? If so, that's strong evidence the event was dispatched to the wrong listener scope. The agent is ready to run but the completion event that should trigger its next turn went somewhere else.
Tracking this for Claudiverse (fleet visibility tooling for multi-agent Claude Code sessions). Background task completion reliability is load-bearing for the class of workflows we're building on top of the agent system. Happy to share structured repro transcripts if useful.
Consolidated evidence plus a working external workaround, for anyone hitting this and for prioritization.
Confirmed scope. This is a scheduler gap, not notification plumbing: an in-process subagent has no wake inlet at all — it advances only on a synchronous tool-call return or an inbound
SendMessage. The same missing inlet surfaces independently in #77578, #76594, #76681, #75043, #68749, #77300, #78434, and #20754, and is framed as a feature request in #76203 ("a subagent has no interrupt inlet"). Two sharp edges from our repros: Monitor arms inside a subagent but its wake is dropped, not queued (#77300 has a timestamped repro), while top-level Monitor and background-Bash wakes deliver fine — the asymmetry is subagents only.Working workaround, verified live on 2.1.214. We rebuilt our codex-dispatch plugin around an external steering plane (a per-user daemon with a per-agent directive mailbox) and confirmed the harness already exposes enough seams to deliver an external wake, through four rungs:
additionalContextinjection on the child's next tool call.SendMessagerelay for a child that finished before delivery — children must be primed by a greeting directive first, or they refuse the relayed wake as prompt injection.Rung 1 fully substitutes for the missing background-completion wake: the child dispatches async, parks, and is woken on completion with its result on disk. So the capability is schedulable today — it just takes a daemon, an MCP server, and a hook pack to reach what a first-class wake inlet would give directly.
**Another repro (macOS, Claude Code, Opus 4.8) — a subagent idles while its own background Bash task runs to completion**
Environment: Claude Code CLI, macOS (Darwin 25.5). A background subagent spawned via the Agent tool with
run_in_background: true, which then launched a long-running (~5–10 min) background Bash task (a build → push → cloud-update pipeline). So the shape is nested: background subagent → background Bash task.Observed sequence:
idle_notification { idleReason: "available" }— repeatedly — carrying a stale summary ("retrying now") that no longer reflects reality.Impact: wasted wall-clock and actively misleading status. The parent repeatedly believed work was stalled or un-started when it had in fact progressed or finished. In our case the parent's out-of-band poll even crossed with the subagent's still-in-flight task, yielding contradictory status between the two.
Additive to the original report:
idle_notificationsummaries emitted while the task is genuinely mid-run (looks related to #73647).What would fix the pain: resume/notify the spawning subagent when its background Bash task exits (success or failure), and don't emit
idle_notifications whose summary describes an action that hasn't actually run yet.This is a resume-path bug with real cost: the subagent ends its turn waiting on background Bash, the work finishes on disk, and nothing wakes the teammate — so the main session either redoes the work or leaves half-finished state.
Pattern that has worked as a host-side guard until the runtime wires completion into the subagent mailbox:
run_in_background: truefrom an in-process subagent as unsupported unless the product documents a wakeup channel for that subagent id.The "finished work sits on disk while the agent idles forever" case is worse than a crash; it burns tokens on silence.