Background tasks started by a non-root sub-agent become permanently orphaned once that sub-agent's turn ends

Status Open
Reported on v2.1.208
Maintainer reply None cached
Activity 4 comments · opened Jul 14, 2026

Title: Background tasks started by a non-root sub-agent become permanently orphaned once that sub-agent's turn ends

Claude Code version: 2.1.208

Summary

A background task (Bash run_in_background: true, likely also applies to a nested
Agent/Task dispatch) started by a sub-agent that is not the root session becomes
completely untrackable — not pollable via TaskOutput, not stoppable via TaskStop,
no completion notification ever surfaces — the moment the spawning sub-agent's own
turn ends. This isn't a routing gap (e.g., "the notification goes to the wrong
place") — the task appears to vanish entirely from the root session's task registry.

Repro steps

  1. From a root session, dispatch a sub-agent (Agent tool).
  2. Within that sub-agent's own turn, have it start a Bash command with

run_in_background: true (e.g., sleep 25 && echo done), then immediately report
the assigned task_id in its final message without waiting on it, polling it, or
calling TaskOutput, and stop.

  1. Back in the root session, once notified that the sub-agent's own turn ended, call

TaskOutput(task_id=<the id the sub-agent reported>, block=false).

Expected: either the background task is discoverable and its eventual completion
is reported to root somehow, or at minimum TaskOutput returns a real status
(running/completed) for a task that verifiably exists.

Actual: TaskOutput returns No task found with ID: <id>. The task is invisible
to root immediately, well before the sleep 25 would even complete. TaskList shows
no trace of it either.

Why this matters

This breaks any multi-level agent architecture where an intermediate (non-root) agent
needs to delegate work asynchronously — e.g., an orchestrator dispatching a persistent
"lead" sub-agent, which itself dispatches further sub-agents for individual work
batches. If any of those non-root dispatches ever background something (intentionally,
or because a tool defaulted to backgrounding despite the caller not asking for it), the
work is silently lost with no way for anything in the session tree — including the
root — to recover it, retrieve its output, or even learn it's stuck.

We hit this as the apparent root cause of real, multi-hour hangs in an autonomous
overnight orchestration workflow (nested sub-agent backgrounds a test run, the
immediate parent waits for it forever, and even the top-level session has no way to
intervene since it can't see the orphaned task at all).

Notes

  • A separate, possibly related observation: the harness's own boilerplate

task-notification text states "A task-notification fires each time this agent stops
with no live background children of its own" — in our test, the parent's own
completion notification fired promptly despite it having a live background Bash
child at that moment. Not sure if that's expected behavior for raw Bash children
specifically (as opposed to nested agent children), but flagging it as a possible
related inconsistency.

View original on GitHub ↗

3 Comments

stefanrusek · 1 month ago

Confirming this also happens with a nested Agent dispatch, not just a backgrounded Bash call — the exact case this report's own "Notes" section flagged as unconfirmed ("likely also applies to a nested Agent/Task dispatch"). Second independent occurrence, different repo/session from the original report.

What happened:

  1. From the root session, I dispatched a sub-agent (call it A) to do a merge task.
  2. Sub-agent A determined the work was large enough to fork its own nested sub-agent (call it B) to do the actual work in an isolated git worktree — a legitimate pattern for scoping risky/large file operations.
  3. Sub-agent A's own turn ended having reported back to root: "the re-derivation work is underway in a background forked subagent... I'll report back with full details once it completes." Sub-agent A itself completed and yielded at this point.
  4. No completion notification for sub-agent B's work ever reached the root session. I only discovered B had actually finished — successfully, with real commits pushed to a branch — by proactively checking git log/git branch -a much later, because a status check on an unrelated ticket surprised me by pointing at unmerged work that should have been done long ago.
  5. The nested branch B produced sat unmerged and un-reported for a significant span of the session, exactly matching this issue's description of "the work is silently lost with no way for anything in the session tree — including the root — to recover it, retrieve its output, or even learn it's stuck," except here the work did complete successfully; only the notification was lost, not the task itself (task discoverable via git artifacts, unlike the fully-orphaned Bash case in the original report).

Why this is worth tracking here rather than as a separate report: same root symptom (a background/async unit of work spawned by a non-root agent becomes invisible to root once the spawning agent's own turn ends), just triggered via the nested-Agent path this issue already predicted rather than raw Bash. Two separate repos and sessions have now independently hit variants of this same class of bug, which suggests it's a structural gap in how completion notifications propagate through more than one level of agent nesting, not an edge case specific to either report's exact repro.

Practical impact: I've had to adopt a defensive habit of periodically re-checking git state / task status directly rather than trusting that "no notification" means "no news" — which defeats a lot of the point of the async notification system for multi-level agent dispatch.

stefanrusek · 1 month ago

One more data point on the above: this second occurrence was on Claude Code 2.1.215, versus 2.1.208 for the original report — so this isn't specific to one version; it's reproduced across at least two point releases.

kcarriedo · 1 month ago

Confirming this pattern across two codebases, and adding one observation that may help narrow the root cause.

The common thread across the reports here: the task handle is scoped to the session that spawned it. When a sub-agent dispatches a background task and its own turn ends (whether it completes normally or hits a limit), the task's TaskStop/TaskOutput routing goes with it. The parent session has no forwarding address.

A few things that might help the Anthropic team reproduce this:

  • Does the orphaning happen when the dispatching sub-agent exits cleanly vs. when it is forcibly stopped? We've seen both, but the "clean exit" path may be the harder one to catch in tests because the sub-agent looks like it finished successfully.
  • Is the task handle registered at spawn time in any persistent store, or only in session memory? If session memory only, then any session transition -- even a clean one -- drops the handle.
  • When the background task completes after orphaning, does its output go anywhere, or is it silently discarded?

For context: we've been building supervisor logic for multi-agent Claude Code workflows (tracking process groups across session boundaries, killing orphaned workers when the parent exits) and the pattern you're describing is the most expensive failure mode we've hit. The fix that worked for us was registering the full process group at spawn time and treating session exit as a kill signal for any descendants that hadn't already completed -- but that only works when you own the orchestration layer. When the sub-agent itself spawns the background task, there's no external hook to catch the orphan.

Happy to share more specifics on the session boundary behavior we've observed if it helps.

Showing cached comments. Read the full discussion on GitHub ↗