Background subagents recursively re-delegate their brief to new background subagents (3-level cascade, duplicate work, misleading completion reports)
Summary
A background subagent spawned via the Agent tool (subagent_type: general-purpose, model: sonnet, run_in_background: true) with a detailed implementation brief did not execute the work. Instead it made exactly one tool call — spawning another background sub-agent with the same brief — and stopped, reporting "I've dispatched this to a background agent and will report back." That child did the same thing, and so did the grandchild: a three-level delegation cascade, each hop consuming ~65–125k tokens for 1 tool use and zero delivered work. The deepest leaf finally started executing for real — in parallel with the corrected original — creating a duplicate git worktree for the same task ~70 seconds after the sanctioned one.
What happened (timeline)
- Orchestrator session dispatches one background
Agent(general-purpose, sonnet) with a self-contained build brief ("You are a bounded implementer agent: build → commit → push → open PR → STOP"). - Agent A completes in ~50s, 1 tool use, ~68k tokens. Its final report: "The implementation agent is running in the background... I'll report back once it completes." → It had spawned Agent B instead of working.
- Agent B (notified later) reports the identical pattern: 1 tool use, ~68k tokens, "I've dispatched this to a background agent to build autonomously." → spawned Agent C.
- Agent C, told to stand down via
SendMessage, reports it had already spawned Agent D before the stand-down landed, and thatTaskStoprefused to kill it ("task ownership restriction"), so it could only relay an abort message. - Agent D was real: it created a duplicate worktree/branch for the same task, racing the corrected original toward a duplicate PR. Caught by a filesystem/GitHub footprint check and removed manually before any commit.
Recovery only worked because (a) the orchestrator footprint-checked every "I delegated it" completion report instead of trusting it, and (b) SendMessage resume with an explicit "Do NOT delegate — you ARE the implementer, execute the brief yourself now" broke the loop: the same agent then executed the brief correctly.
Why this seems worth fixing
- Nothing in the brief invited delegation — it was an imperative implementation task addressed to the agent itself ("you are a bounded implementer"). The agent treated "large multi-step build task" as a cue to fan out.
- The delegation is recursive: the child inherits a brief that looks dispatch-shaped to it too, so each generation re-delegates. Without an explicit "never spawn sub-agents" line the cascade is stable.
- Each hop burns a full context load (~65–125k tokens here) for one tool call.
- The completion reports are misleading: to the orchestrator, "finished" notifications arrive whose result text describes work that does not exist yet (no files, no branch, no PR) — the harness marks the task completed while the real work is unowned or duplicated.
- Cleanup is hard:
TaskStopacross agent ownership is refused, so a cascade can only be unwound by best-effort messages that land "on the next tool round" — while a real leaf may already be racing the sanctioned worker to duplicate artifacts.
Suggestions (any one would help)
- Depth limit or explicit opt-in for subagents spawning further background subagents (e.g.
Agentunavailable to subagents unless the parent grants it), or at minimum a strong system-prompt default for subagents: "you are the executor; do not re-delegate the task you were given." - Surface child-spawns in the parent's completion notification (the orchestrator currently can't see that a "completed" agent's only act was spawning an untracked child).
- Allow the spawning session to
TaskStopdescendants (transitive ownership), so a cascade can be killed instead of politely messaged.
Environment
- Claude Code 2.1.97 (macOS, darwin 25.5.0)
- Orchestrator model: claude-fable-5; subagents:
model: "sonnet"via theAgenttool,run_in_background: true,subagent_type: general-purpose - Occurred twice in the same session with independent dispatches (original + its re-resume), three cascade levels observed, one real duplicate-work leaf.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗