[BUG] SendMessage tool description denies any address syntax while uds:<socket> addresses work and are documented elsewhere in the same build
Preflight
- [x] I have searched existing issues; the closest are #84920 (the same schema-vs-transport mismatch for
bridge:addresses cross-machine) and #84894 / #86019 (name and self-identification gaps) — none covers the same-machineuds:form or the description's affirmative denial that any address syntax exists - [x] This is a single bug report
- [x] I am using the latest version of Claude Code (2.1.251)
Summary
The SendMessage tool description presented to the model states, about ListAgents rows: "the name IS the address; there is no separate address syntax", and its to parameter schema documents only names, main, and agent ids.
This is contradicted by the same build three ways: other tool descriptions embedded in the same binary accept "an explicit uds:<socket> / bridge:<session id> address"; the cross-session messaging docs present the uds:-prefixed socket path as the session's own inbox address (/status → Peer address row); and a live SendMessage with a raw uds: address delivers successfully.
The description doesn't merely omit the address forms — it affirmatively denies they exist, which steers the model to treat working address-based automation as broken.
Reproduction
- In a session on 2.1.251, read the
SendMessagetool description andtoschema.
- Result: "the name IS the address; there is no separate address syntax";
todocuments a name from ListAgents, a teammate name,main, or a background agent's agentId — no address form.
- Run
stringson the release binary and search foruds:.
- Result (excerpts):
``uds:<socket>
, or an explicit / bridge:<session id> address.``
Recipient: a peer session name from ; , or an explicit uds:<socket> / bridge:<session id> address
- With a second live session on the machine, find its socket under
/tmp/cc-socks*/(also shown in that session's/status→ Peer address) and callSendMessagewithto: "uds:/tmp/cc-socks/<pid>.sock".
- Result:
{"success":true,"message":"… → uds:/tmp/cc-socks/<pid>.sock","msg_id":"33da2aeb-…"}— the send is accepted and assigned a message id.
Scope
- This is a schema/description consistency bug, not a transport bug: the transport works as (elsewhere) documented. The defect is that the model-facing description denies the address form the build accepts and other surfaces document.
- Distinct from #84920, which covers
bridge:<session id>cross-machine and the false "reply-only" claim. This report is the same-machineuds:form and the "no separate address syntax" sentence specifically.
Why this matters
The uds: address is the only deterministic way a session can identify itself to other sessions. The only officially documented to form for cross-session sends is the session name (plus listing-scoped [ref]s, main, and in-session agentIds), and a name cannot serve as a self-identifier a session hands out:
- No environment variable exposes the session's own name. The exported set is
CLAUDE_CODE_MESSAGING_SOCKET,CLAUDE_CODE_MESSAGING_TOKEN,CLAUDE_CODE_SESSION_ID, andCLAUDE_PID— so aSessionStarthook or bootstrap script that wants to tell peers "reach me here" has the socket path and nothing else. - Names are non-deterministic as identifiers even when known: they are harness-generated, changeable mid-session with
/rename, and silently renamed to a variant when a new session collides with an existing name — so a name emitted at session start can be stale or ambiguous by the time a peer uses it. [ref]s are explicitly non-transferable: the schema says a ref "you did not just read from a listing or an error will not resolve", so one carried in a message is useless to the receiver.CLAUDE_CODE_SESSION_IDmatches no documentedtoform (its only plausible consumer is thebridge:<session id>form, itself undocumented — #84920).
That leaves uds:$CLAUDE_CODE_MESSAGING_SOCKET as the only identifier that is exported to the session's own scripts and hooks, stable for the session's lifetime, and accepted by SendMessage — which is why bootstrap scripts and multi-session handshakes are built on it.
The description's affirmative denial then does real damage, because capable models follow tool text literally and weigh it above a user's own scripts. Concretely: an automated maintenance agent of ours read the schema, concluded a session-bootstrap script's (correct) statement that to accepts the socket address was stale, and raised a PR dismantling a tested multi-session handshake.
Expected
Any of, in preference order:
- Document the accepted address forms (
uds:<socket>,bridge:<session id>) in theSendMessagedescription andtoschema, as the binary's other recipient descriptions already do. - If the forms are meant to be internal, state their support level explicitly ("addresses such as
uds:… are accepted but unsupported/subject to change") rather than asserting no address syntax exists — and note that deprecatinguds:without a replacement would leave sessions with no deterministic self-identifier at all, since no documentedtoform is derivable from the session's environment. - At minimum, reconcile the description variants within one build so the model isn't shown a sentence its own tool surface elsewhere contradicts.
Related issues
- #84920 —
bridge:addresses work cross-machine while every surface says reply-only (same class, different form and claim) - #84894 — display names not exposed in ListAgents or accepted by SendMessage
- #86019 (closed) — a session cannot identify itself in ListAgents
Is this a regression?
I don't know when the "no separate address syntax" wording was introduced; observed on 2.1.247 and 2.1.251.
Environment
- Claude Code: 2.1.251 (also observed with 2.1.247 as the running build)
- OS: macOS 15 (Darwin 25.4.0)
- Model: claude-fable-5