Cross-session messaging: subsystem blind to live Remote Control connection — discovery empty, sends silently undelivered (both directions)
Summary
Cross-session messaging (docs/en/cross-session-messaging) fails cross-machine in both directions on
a two-machine setup where every documented precondition is met and live-verified. The root symptom:
the messaging subsystem reports "Remote Control is not connected" while the same session's Remote
Control connection is provably live (visible "Remote Control is active" banner on one machine; abridge_state: connected host-log entry with no subsequent disconnect on the other). From that
false internal state: ListAgents never shows remote/cloud rows, name-addressed sends fail with
"No agent named ... is reachable," and sends to an explicit bridge address return success:true
but are never delivered (no trace in the receiving machine's logs, no approval dialog, no
sender-side send record).
Environment
| | Machine A | Machine B |
|---|---|---|
| OS | Ubuntu Linux | macOS |
| Claude Code | 2.1.233 | 2.1.229 (desktop-bundled) |
| Entrypoint | claude-vscode | claude-desktop |
| Auth | first-party (same account, same org on both) | same |
| remoteControlAtStartup | true | true |
| Killer env vars (DISABLE_TELEMETRY etc.) | none | none |
| RC live proof | "Remote Control is active" banner (screenshot) | host log [remote-control] bridge_state: connected, no disconnect after |
| Same-machine messaging | works (ListAgents + SendMessage verified) | works |
Both sessions bind inbox sockets (/status peer address present; CLAUDE_CODE_MESSAGING_SOCKET
exported). /list-agents is recognized on both.
Steps to reproduce
- Two machines, same first-party account/org, both ≥ 2.1.225,
remoteControlAtStartup: true. - Connect Remote Control on a session on each machine (banner/
/rc activeconfirmed visible). - On either machine, run
ListAgents(or/list-agents). - Attempt
SendMessageto the other machine's session by name. - Attempt
SendMessageto the other machine's explicit bridge address
(bridge:session_<id>, id derived from the replBridgePlaceholders key in .claude.json).
Expected
- Step 3: the other machine's RC-connected session appears, labeled "Remote Control"
(per docs: "shown while this session is connected to Remote Control").
- Step 4/5: message delivered, or held per inbound rules with a visible approval dialog.
Actual
- Step 3: only same-machine sessions listed, both directions, repeatedly over ~6 hours.
No "Remote Control", "cloud", or "offline" rows ever.
- Step 4:
{"success":false,"message":"No agent named '<name>' is reachable."}(both directions). - Step 5:
success:truewith the parenthetical **"(one-way: Remote Control is not connected, so
the receiver cannot address a reply to this session)"** — on BOTH machines, each of which had a
live RC connection at that moment. No delivery: no dialog on the receiver (watched live), no
inbound trace in the receiver's logs, no send record in the sender's debug logs. Both directions.
Diagnosis evidence
- The "not connected" claim and the live-connection proof coexist on the same machine minutes
apart — on the Mac, the contradiction is between the harness receipt and the app's own
main.log bridge_state: connected entry (machine-written, timestamped at session start,
no disconnect logged after).
- Reproduced across two entrypoints (claude-vscode, claude-desktop) and two versions
(2.1.233, 2.1.229), both directions, same account+org (verified from oauthAccount on both).
replBridgePlaceholdersentries exist for the sessions on both machines
(hasUsedRemoteControl: true, surfaces mobile/desktop) — RC bridge sessions were created and
the user actively drives both sessions from the mobile app over those connections.
- Feature-flag evaluation is not the cause: no
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC,
DISABLE_TELEMETRY, DO_NOT_TRACK, or DISABLE_GROWTHBOOK in shell env or settings env
maps on either machine, and same-machine messaging (which shares the feature flag) works.
Impact
Cross-machine session messaging is unusable on this setup despite meeting every documented
requirement. Additionally, SendMessage returning success:true for a message that is never
delivered and leaves no trace makes the failure silent — the sender cannot distinguish delivery
from a dropped message.
Suggested focus
Wherever the messaging subsystem queries RC connection state, it does not see connections
established by the VS Code extension banner flow or the desktop app (and possibly /remote-control
generally). ListAgents returning zero remote rows also appears to swallow any upstream error, so
an auth/state failure is indistinguishable from "no other sessions."
Happy to provide session ids, timestamps, or logs on request.
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Same failure on a different pair of entrypoints — and I can narrow the variable: it reproduces on a single machine, where the entrypoint is the only thing that differs.
Ubuntu 24.04, Claude Code 2.1.232, one host, one account, both sessions RC-connected at the same moment:
| Session | Started as |
entrypointin~/.claude/sessions/<pid>.json| Sees other-machine sessions? ||---|---|---|---|
| A |
claude remote-control(server mode, under a systemd unit) |sdk-cli| no || B |
claude --remote-control(plain interactive, in tmux) |cli| yes |B's
/list-agents, seconds after A returned local peers only:Note A is listed by everyone else, with live idle/running status. It advertises to the backend correctly; it just never consumes the roster.
The silent-drop half reproduces too. From the second machine,
SendMessageto A by name returnssuccess:truewith a msg_id and"→ rc-sess-1 (a Claude session on another machine, over Remote Control)"— and nothing arrives. Verified on the receiving host: A never got it, no sibling session's transcript was touched, and grepping every transcript on that box shows every cross-session message ever received there carriesfrom="uds:/tmp/cc-socks/<pid>.sock"— a local socket. No cross-machine message has ever landed on it.Ruled out on the receiving side: no
crossSessionInbound/isolatePeerMachines/SendMessage|ListAgentsdeny rules; none of theDISABLE_TELEMETRY,DO_NOT_TRACK,CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC,DISABLE_GROWTHBOOKvars set; permission modeauto(delivers rather than holds, per the docs); both sessions bind inbox sockets;/list-agentsrecognized on both.Across this report and mine, the failing entrypoints are
claude-vscode,claude-desktopandsdk-cli, while plaincliworks — consistent with the roster / RC-connection wiring existing only in the interactive CLI path.Still reproduces on 2.1.234 — and my earlier
entrypointtheory was wrongRetested today on 2.1.234, hoping these two 2.1.234 changelog lines covered it:
Neither fixes this. It still reproduces, and the retest lets me correct my previous comment.
⚠️ Correction:
entrypointis not the discriminatorI previously reported the split as
entrypoint: sdk-cli(broken) vscli(working), read from~/.claude/sessions/<pid>.json. On 2.1.234 that no longer holds — a plain interactiveclaude --remote-controlnow also reportssdk-cli, yet it works fine. Same field, both values now identical, behaviour still different. Anyone filtering on that field will chase a ghost.The actual discriminator: server mode vs single-session mode
Ubuntu 24.04, one host, one account, both sessions 2.1.234, measured within the same minute:
| | Session A | Session B |
|---|---|---|
| Launch |
claude remote-control --name … --capacity 3(server mode, under a systemd unit) |claude --remote-control(single-session, in tmux) ||
entrypoint|sdk-cli|sdk-cli||
ListAgents| 1 peer | 4 peers |B's view:
A's view, same minute:
foss-it-41in B's list is session A (started 11m earlier). So B sees A; A cannot see B.The pattern in what goes missing
A sees the
interactive-kind peer but none of theRemote Control-kind entries.daedalus — FOSS Dev [5201bf]— a different systemd unit's Remote Control session on the same host, live and idle at the time. Visible to B, invisible to A.daedalus — FOSS IT [a08d4e], which is A's own bridge. Self-exclusion could legitimately explain that one, so I'm not leaning on it — but combined with the above it suggests the supervisor-hosted session's view is filtered by session kind, not merely truncated.That last point matters against the "list was too long" theory in the 2.1.234 note: 4 entries is not a truncation case, and A's missing entries are kind-correlated rather than arbitrary.
Repro
claude remote-control --name foo --capacity 3(any host process manager; mine is a systemd unit).claude --remote-controlin tmux.ListAgentsin each within the same minute.Remote Control-kind peer.Methodology note for anyone verifying
An empty or short peer list is not evidence on its own. I nearly recorded a false "fixed" here: after restarting the unit onto 2.1.234 my count was unchanged at 1 — but the restart had itself killed two of the sessions the earlier control saw, so "1" was consistent with both "still broken" and "nothing left to find". Only re-running the working-mode control contemporaneously separates them. Please pair any check with a known-live control session started the same way.
Thanks for the detailed report (and the follow-up narrowing it to server mode). Root cause confirmed: the peer-listing surface only consulted the Remote Control connection held by an interactive session, so sessions run under
claude remote-control(server mode) and other SDK-hosted sessions never saw the roster and reported "Remote Control is not connected". A fix is up for review that lets those sessions use their own connection forListAgents/SendMessageand identify themselves correctly to peers; verified end-to-end against a real binary in server mode. Will follow up here with the release that carries it.