SubagentHandback from an in-process teammate's subagent fails with "the agent that spawned you is no longer running" while the teammate is alive (auto mode, 2.1.280)

Status Open
Reported on v2.1.270
Maintainer reply None cached
Activity 3 comments · opened Sep 23, 2026

Summary

With Agent Teams enabled and the session in auto mode, an in-process teammate that spawns its own foreground subagent never receives that subagent's report. The subagent's SubagentHandback call returns

{"success":false,"message":"Nothing was sent: the agent that spawned you is no longer running."}

while the teammate is alive and blocked on the Agent call. The teammate's Agent call then ends with "The subagent ended without delivering a report through SubagentHandback", and a copy of the report surfaces in the lead session's conversation as an <agent-message> instead. Depth 2 to depth 1 hand-back (grandchild to the teammate's subagent) works; it is the last hop into the teammate that fails.

The same test passes on 2.1.270. Builds between 2.1.270 and 2.1.280 were not tested.

Environment

  • Claude Code 2.1.280, native install, macOS 26 (Darwin 25.6.0)
  • CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1, teammateMode: "in-process", permission mode auto
  • Last passing build: 2.1.270 (same rig, same test)

Steps to reproduce

  1. Start a session in auto mode with Agent Teams enabled.
  2. Spawn a named teammate with the Agent tool (name set, run_in_background omitted). The spawn metadata shows taskKind: in_process_teammate, spawnDepth: 0.
  3. Have the teammate spawn one further subagent with the Agent tool (no name, foreground) that returns a token, and optionally have that subagent spawn a grandchild.
  4. Watch the child's SubagentHandback result and the teammate's Agent result.

Expected: the child's report is delivered to the teammate as the Agent tool result.

Actual (timestamps from one run, 2026-09-22 UTC):

  • 19:44:54, 19:44:59, 19:45:10: the child's SubagentHandback refused with the message above; the teammate was alive and waiting the whole time.
  • 19:45:15: the teammate's Agent call returned "The subagent ended without delivering a report through SubagentHandback".
  • The report appeared in the lead's conversation as <agent-message from="a2f8acccb4de211c1">, and ListAgents in the lead listed that child under the lead's subagents rather than the teammate's.
  • The teammate could recover the tokens by resuming the child with SendMessage, which is not a workable pattern for pipelines that fan out.

What the binary does

Reading the 2.1.280 bundle:

  • The hand-back path is active only in auto mode and behind the feature flag tengu_lively_waffle. The code default is false on 2.1.270 and true on 2.1.280, and the served value is true here.
  • On refusal, the failing branch is the liveness check on the spawner's task-registry entry (the recipient is the spawner's task id). A live in-process teammate that is blocked on its own Agent call does not satisfy it.
  • Only a backgrounded child is rerouted to the main session. Per the sub-agents docs, an in-process teammate's children are always foreground, so a teammate's child has no delivery path at all.
  • CLAUDE_CODE_SENDMESSAGE_HANDBACK is read in the same function, but through an env accessor built from an empty schema, so it is always undefined and cannot be used to opt out. It is not in the environment-variables docs either.

DISABLE_GROWTHBOOK=1 does not help because the code default is already true on 2.1.280.

Impact

Any workflow where a teammate fans out to subagents in auto mode loses the results. Running the lead in a non-auto mode or flattening the spawn tree are the only ways around it, and neither fits pipelines that rely on teammates doing the fan-out.

Requests

  1. Let the hand-back resolve an in-process teammate parent: accept its registry entry, or reroute the foreground child's report to that teammate's inbox the way a backgrounded child's report reroutes to main.
  2. Wire CLAUDE_CODE_SENDMESSAGE_HANDBACK to the real env schema and document it, so operators can opt out until the fix ships.

View original on GitHub ↗

3 Comments

umekatu · 20 days ago

Same failure on Windows, at scale, on 2.1.276 and 2.1.281 (both after the 2.1.270 last-good build you found).

Environment: Windows 11, native install, CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1, in-process teammates, permission mode auto (defaultMode: "auto"). No hook in this setup touches SubagentHandback or rewrites Agent input.

Data from one session's transcripts, 2026-09-24 00:00 → 2026-09-26 03:00 JST (about 51 hours; the session runs a campaign lead as an in-process teammate, which spawns workers):

  • 197 child subagents got {"success":false,"message":"Nothing was sent: the agent that spawned you is no longer running."} from SubagentHandback (50 on 2.1.276, 147 on 2.1.281); 76 of them on 2026-09-24 alone.
  • For the 68 children of that first day whose spawner I could pair, the spawner (the in-process teammate) was mid-turn at the moment of the refusal in all 68 — blocked on the Agent call that spawned the child; its tool_result arrives a few seconds after the child ends. 61 of the 68 were foreground unnamed spawns; 6 were run_in_background: true spawns and failed the same way.
  • The teammate's Agent result then reads The subagent ended without delivering a report through SubagentHandback, so no report was delivered. Its unsent text is not shown., as in your report.
  • [handback-send-enforce] re-prompts up to 3 times per burst and then goes quiet (176 of the 197 children got exactly 3, the rest are multiples of 3 across several bursts); the "not available in this run" countermand is never emitted for this case.
  • Cost: the refused attempts plus the answers to the reminders were 1,140 extra full-context calls re-sending 229M input tokens over those 51 hours.

The 2.1.281 bundle still refuses at the liveness branch (gWe(taskRegistry.get(recipient)) is false for the live teammate), with the cap handbackBounces < 3 on the reminder.

Workaround in use: workers are told to deliver the report with SendMessage to the teammate and not to retry the hand-back; the Agent return stays empty.

lukasdatte · 18 days ago

Still reproducible on 2.1.283, Linux (Ubuntu 24.04, native install), in-process teammates, permission mode auto. Reproduced with no hooks that produce output (only two SubagentStop/lifecycle logging hooks that print nothing and exit 0), so hooks are ruled out.

Minimal repro: a named in-process teammate spawns one foreground subagent (haiku, no name) whose only task is to return a fixed token. The child's SubagentHandback is refused four times with Nothing was sent: the agent that spawned you is no longer running., while the teammate is blocked in the same Agent call and was never restarted (child meta: requestShape: "foreground", spawnDepth: 1).

Two additions to the report above:

  1. Cost of the enforce loop. After each refusal the harness re-prompts the child with [handback-send-enforce] Your report has not been delivered…, so the child runs again and rewrites its final message each time. In our first occurrence that was 4 re-runs and roughly 95k tokens for a task that needed a few hundred. The final text left at the end is the child's explanation of the failure, not its report.
  2. ID mismatch (hypothesis, not proven). The child's metadata names its parent as parentAgentId: "a<teammate-name>-<16 hex>", while the team config addresses the same teammate as <teammate-name>@session-<id>. If the liveness check that decides "no longer running" compares against the second form, it would never find the parent — which would match "the teammate is alive but the hop into it fails".

Workaround we use: a SubagentStop hook receives the complete final text in last_assistant_message (not truncated; 14 779 characters in a test) and writes it to a file per agent. The waiting teammate can read the report from there. Note that with the enforce loop the first file of the child holds the actual report; later ones hold its explanations.

DeathSy · 12 days ago

Still reproducing on 2.1.288 (macOS, auto mode). Additional findings that go beyond the original report:

  1. Foreground spawns fail too. A background teammate spawning subagents without run_in_background (a single call and two parallel calls in one message, model sonnet, general-purpose, prompt "Reply with exactly the word pong and nothing else. Do not call any tools.") gets this as the Agent tool's return value every time:

> The subagent ended without delivering a report through SubagentHandback, so no report was delivered. Its unsent text is not shown. Send the agent a message (SendMessage) to ask it to deliver its report.

  1. SendMessage to the teammate is misrouted. When the subagent falls back to SendMessage with the teammate's name as to, the message never reaches the teammate. It lands in the main session's inbox instead. So there is no working channel from a teammate's subagent back to that teammate.
  2. handback-send-enforce loops. After SubagentHandback fails with "the agent that spawned you is no longer running" (while ListAgents shows the teammate running), the built-in handback-send-enforce hook keeps demanding a retry. This happens even after the subagent has delivered its result via SendMessage, so the agent loops until it gives up.
  3. Cost: each of those one-word "pong" subagents made 3–4 tool calls (failed handback retries) and used ~208k tokens over ~23 s.

Seen independently in two separate sessions (different projects), each with a background opus teammate spawning sol and opus/sonnet subagents. Workaround we use: teammates don't spawn subagents; the main session spawns workers and relays results.

Suggested fixes: route subagent handback (and SendMessage to the teammate's name) to the in-process teammate; and have handback-send-enforce accept a successful SendMessage as delivery, or stop after one failed retry when the spawner is reported gone.