[BUG] Teammate subagents of a forked-skill agent cannot reply to their parent; SendMessage to "team-lead" false-succeeds into an orphaned inbox
Summary
Subagents spawned as named mailbox teammates by a forked-skill background agent have no working reply path back to their parent — and one of the failure modes returns success: true while dropping the message. The parent deadlocks waiting for replies that can never arrive, with success signals on both sides.
Environment
- Claude Code 2.1.228, macOS (darwin 25.5.0)
- Model: claude-fable-5
- Trigger:
/code-review max --fix <path>(the skill runs as a forked background agent and fans out ~10 "finder" subagents via the Agent tool withname:set, mailbox-style)
What happened
The review agent spawned 10 named finder agents. Each spawn returned "Spawned successfully… will receive instructions via mailbox." All 10 finders ran to completion (their transcripts are on disk as top-level session .jsonl files) and each tried 3–4 times to deliver its findings. Every route failed:
SendMessage({to: "main"})→{"success":false,"message":"You are the main conversation — \"main\" addresses you. Send to a named agent instead."}
Each finder's context treats the finder itself as the main conversation, so the documented reply path for background subagents doesn't exist from inside this spawn mode.
SendMessage({to: "code-review"})(the parent's registered name) →{"success":false,"message":"No agent named 'code-review' is reachable."}
The forked-skill parent's name is registered only in the original session's registry; its own children can't resolve it.
SendMessage({to: "team-lead"})→{"success":true,"message":"Message sent to team-lead's inbox","msg_id":"…"}
This is the worst one: the parent is not running as a team lead and nothing ever drains a "team-lead" inbox, so the message is dropped after a success response.
Meanwhile the forward direction worked fine: the parent's SendMessage pings to the finders returned "Message sent to finder-X's inbox" and demonstrably woke all 10 finders within a minute. So the channel is one-way, and both directions report success.
Net effect: the parent sat idle "waiting for finder reports" indefinitely. From the outer session it looked healthy — the parent's spawn results, its pings, and the finders' team-lead sends all said success. I only found the findings by grepping the finders' transcripts and hand-delivering the payloads to the parent.
One extra footgun for anyone debugging the same thing: these teammate-style subagents do not write subagents/agent-*.jsonl files — their transcripts are top-level <uuid>.jsonl session files under ~/.claude/projects/<project>/, and the transcript does not contain the agent's own registered name.
Expected
- A subagent should always have at least one working address for the agent that spawned it (parent name resolvable, or
mainrouting to the spawner). SendMessagemust not returnsuccess: truefor an inbox no consumer will ever drain — an unreachable recipient should be an error, like case 2.
Related
- #74113 (background agents go idle without delivering their final SendMessage report) — similar symptom; in my case the sends themselves fail or false-succeed, so a re-ping cannot recover it.
- #25135 (closed, stale) — same false-success-into-mismatched-inbox mechanism as case 3, reported against Agent Teams.
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Update with new evidence: the "team-lead" messages were not silently dropped after all — roughly 2 hours after the sends, every queued teammate message (idle notifications plus the full findings payloads) was delivered in a single batch to the main conversation of the session, wrapped as teammate-messages. Not to the parent agent that spawned the teammates, and long after those teammates had been stopped and the workflow manually recovered from transcripts.
So the more precise defect for case 3 is misrouting plus unbounded delay rather than a pure drop: SendMessage returns success, the parent (the only party waiting on the reply) never receives it, and the payload eventually surfaces to the top-level session hours later when it can no longer unblock anything. Cases 1 and 2 ("main" self-reference, parent name unresolvable) are unchanged.
Another instance of case 2 on a different spawn shape — plain background
Agentdispatches, no Agent Teams and no forked skill. There's a second, separable failure here too: the spawner never received its child's completion notification.Environment: Claude Code 2.1.229, Linux, model
claude-opus-5[1m]. Subagents dispatched with theAgenttool using a customsubagent_typefrom.claude/agents/; noname:set on any spawn.Shape: top-level session → background subagent A (custom type) → A dispatches its own background child B with
isolation: "worktree".1. B cannot address A (case 2, new spawn shape)
B finished its work and tried to report to A with
SendMessage({to: "<A's subagent_type>"}), twice:B's toolset had no
ListAgents, so it had no way to discover a valid address for A — and no way to learn that what it held was the wrong kind of identifier (an agent type, not a registered name). It retried, gave up, and reported the failure in prose inside its result.2. B's completion notification did not reach A — it reached the top-level session
A's spawn result for B carried the usual contract: "You will be notified automatically when it completes… Do NOT Read or tail this file."
That notification never arrived. Checked against A's own transcript JSONL:
<task-notification>, and it is not B's completion — it is aMonitor eventwith an unrelated task-id.<B-id>.outputdirectly — the exact action the spawn result instructs agents not to take. A's transcript shows repeated reads of that path.So for a subagent-spawned child the completion notification appears to be routed to the root session rather than to the spawner, while the spawner is told to expect it and told not to read the output file. The documented channel and the working channel are different ones, and nothing tells the spawner that.
Why this costs something even though nothing deadlocked
A did eventually get B's findings, so no deadlock — but only by violating its own instructions. And B had a working result channel (its return value) the entire time and could not tell: with no
ListAgentsand no address for its spawner in context, "can I reply to my parent?" is unanswerable from inside the child, so B spent turns on a route that cannot succeed and then reported a non-problem as a problem for A to reason about.Suggested fixes
Related to #85160 (stable identifier as an address) and #81185 (restricted toolsets leaving no reply path).
(Revision note: an earlier edit of this comment withdrew the notification-routing claim as unverified. I then checked the spawner's transcript directly, and the claim holds — restored above with the evidence that establishes it.)
Another instance of the same false-success shape, on a different platform and with a different reason the inbox has no reader.
Environment: Claude Code 2.1.263, Windows 11 Enterprise 26200.
What happened:
SendMessage({to: "<peer-session-name>"})returnedsuccess: true. Two and a half hours later the message is still sitting in~/.claude/teams/session-<id>/inboxes/<name>.jsonwith"read": false- and that session id no longer appears in the live session list. The recipient session had already exited.So in this variant the inbox is orphaned not because the parent is not a team lead, but because the recipient session is gone. The delivery path does not appear to check recipient liveness at send time, and the sender receives no later signal that nothing will ever read the message.
Both pending inbox entries on this machine are
"read": false; one of the two has a dead recipient.The distinction that seems load-bearing:
success: truecurrently means "written to a mailbox file", not "a live reader exists". A sender that waits on a reply therefore waits forever with a success signal in hand - which matches the deadlock described in the original report.Suggestion: at send time, check whether the addressed session/agent is live (the runtime already tracks live sessions for
ListAgents) and returnsuccess: false- or at minimum a distinct warning - when writing into a mailbox with no live reader.No agent named 'X' is reachablealready exists as a failure mode for unknown names; a known-but-dead recipient could reuse it.For contrast, the other two channels on this machine were reliable over the same period: background agent completion notifications arrived for 244 of 245 launched agents (the one outstanding was still running), and 73 of 73 continuations addressed by agent id succeeded. It is specifically the name-addressed mailbox path that fails silently.