Peer SendMessage reply nudge stamps from= with agent-type name, not reachable session ID, causing infinite unreachable-address loop

Status Fixed / completed
Reported on v2.1.236
Maintainer reply None cached
Activity 2 comments · opened Aug 23, 2026 · closed Aug 27, 2026

Environment

  • Claude Code / VSCode extension version: 2.1.236
  • Entrypoint: claude-vscode
  • Trigger: the built-in code-review skill (bundled in the extension binary — reviews the current session's diff with a two-axis / multi-angle parallel sub-agent pattern)

Summary

When a forked sub-agent (spawned via the Agent tool, running as a sidechain) sends a follow-up peer message to another forked sub-agent asking it to re-confirm or restate something, the injected peer-message wrapper instructs the recipient to "reply via SendMessage to the from= address." In the observed transcripts, from= is populated with the agent-type name used when the sub-agent was originally spawned (e.g. "general-purpose") rather than that sub-agent's actual reachable session/task ID (e.g. a239ef1049a0f28db).

The recipient then correctly calls SendMessage(to: "general-purpose", ...) per the injected instruction, which fails with:

{"success":false,"message":"No agent named 'general-purpose' is reachable.\nCheck the spelling, or use the agent ID from a background agent's spawn result."}

This is architecturally guaranteed to fail every time from= is a type name rather than an address, since agent-type names (general-purpose, Explore, etc.) are never independently addressable — only concrete spawned session/task IDs are.

Observed failure loop

In one session, a verifier sub-agent (task ID a239ef1049a0f28db) sent repeated "please restate your findings" / "you must call SendMessage now, do not finish silently" nudges to multiple finder sub-agents. Each nudge's origin block looked like:

{"kind":"peer","from":"general-purpose","senderTaskId":"a239ef1049a0f28db","name":"general-purpose", ...}

Note senderTaskId correctly holds the real address (a239ef1049a0f28db), but from/name — the fields actually surfaced in the human-readable <agent-message from="general-purpose"> wrapper text — hold the type label instead. Each finder sub-agent:

  1. Had already successfully sent its findings once via SendMessage(to: "a239ef1049a0f28db", ...) earlier in the same run (proving the correct address was known to it at that point).
  2. On receiving the mis-addressed nudge, tried SendMessage(to: "general-purpose", ...) per the injected instruction, got the "not reachable" error, correctly diagnosed that general-purpose is a type name not an address, and declined to retry blindly.
  3. Received the same mis-addressed nudge again shortly after (the verifier re-sent it, apparently because it never received the finder's restated answer, since the finder's reply attempts were failing at the transport layer) — repeating the whole cycle several times per finder sub-agent before the session concluded.

This burned multiple extra turns and a meaningful amount of tokens (tens of thousands per affected sub-agent, per the session's own usage accounting) without any of the "restate" round-trips ever actually landing.

Expected behavior

from= (and name=) in an injected peer-message wrapper should always contain the actual reachable session/task ID of the sender, not the agent-type name it was spawned with — so that "reply via SendMessage to the from= address," which is the literal instruction the harness injects, is always actually followable.

Suggested fix

Populate the peer-message wrapper's from/name fields from the same value already correctly present in senderTaskId, rather than from whatever type/name string was used at spawn time. Alternatively, if from= is meant to be human-readable, keep it separate from the addressable value and make the injected instruction reference the correct field explicitly (e.g. "reply via SendMessage to senderTaskId") rather than telling the model to address using a display label.

Impact

Any skill or workflow that spawns multiple forked sub-agents and has one send a peer follow-up to another (e.g. a verifier round-tripping with finder agents) is susceptible. We've worked around it locally by avoiding the specific built-in skill that triggers this pattern and standardizing on a skill that only does one-shot dispatch-and-collect via the Agent tool's own return value (never sub-agent-to-sub-agent SendMessage), but this is a real bug in the peer-addressing layer that should be fixed upstream rather than routed around per-skill.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗