Cross-session messaging: subsystem blind to live Remote Control connection — discovery empty, sends silently undelivered (both directions)

Status Fixed / completed
Reported on v2.1.233
Maintainer reply ✓ Yes — dhollman
Activity 5 comments · opened Aug 15, 2026 · closed Aug 19, 2026
💡 Likely answer: A maintainer (dhollman, contributor) responded on this thread — see the highlighted reply below.

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; a
bridge_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

  1. Two machines, same first-party account/org, both ≥ 2.1.225, remoteControlAtStartup: true.
  2. Connect Remote Control on a session on each machine (banner//rc active confirmed visible).
  3. On either machine, run ListAgents (or /list-agents).
  4. Attempt SendMessage to the other machine's session by name.
  5. Attempt SendMessage to 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:true with 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).

  • replBridgePlaceholders entries 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.

View original on GitHub ↗

3 Comments

ziouzitsou · 14 days ago

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 | entrypoint in ~/.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:

Other Claude sessions (5):
  [unknown]  ·  local-peer-1  ·  /home/<user>/<projX>
  [unknown]  ·  local-peer-2  ·  /home/<user>/<projY>
  [idle]     ·  remote-sess   ·  Remote Control   <- second machine, WSL2 on Win11, 2.1.233
  [idle]     ·  rc-sess-2     ·  Remote Control
  [running]  ·  rc-sess-1     ·  Remote Control   <- session A itself

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, SendMessage to A by name returns success:true with 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 carries from="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|ListAgents deny rules; none of the DISABLE_TELEMETRY, DO_NOT_TRACK, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, DISABLE_GROWTHBOOK vars set; permission mode auto (delivers rather than holds, per the docs); both sessions bind inbox sockets; /list-agents recognized on both.

Across this report and mine, the failing entrypoints are claude-vscode, claude-desktop and sdk-cli, while plain cli works — consistent with the roster / RC-connection wiring existing only in the interactive CLI path.

ziouzitsou · 12 days ago

Still reproduces on 2.1.234 — and my earlier entrypoint theory was wrong

Retested today on 2.1.234, hoping these two 2.1.234 changelog lines covered it:

Fixed Claude Desktop inter-session messages being silently dropped by the recipient session when cross-session messaging read as disabled […]
SendMessage and ListAgents now say when your account's session list was too long to check completely, instead of treating unseen sessions as absent

Neither fixes this. It still reproduces, and the retest lets me correct my previous comment.

⚠️ Correction: entrypoint is not the discriminator

I previously reported the split as entrypoint: sdk-cli (broken) vs cli (working), read from ~/.claude/sessions/<pid>.json. On 2.1.234 that no longer holds — a plain interactive claude --remote-control now also reports sdk-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:

Peer sessions (4):
  workspace-9b [eefa7c]        ·  interactive      ·  started 2d ago
  foss-it-41 [d79e04]          ·  interactive      ·  started 11m ago
  daedalus — FOSS Dev [5201bf] ·  Remote Control   ·  idle
  daedalus — FOSS IT [a08d4e]  ·  Remote Control   ·  running

A's view, same minute:

Peer sessions (1):
  workspace-9b [eefa7c]        ·  interactive      ·  started 2d ago

foss-it-41 in 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 the Remote Control-kind entries.

  • Unambiguous miss: 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.
  • Also missing from 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
  1. Start a supervisor: claude remote-control --name foo --capacity 3 (any host process manager; mine is a systemd unit).
  2. Separately on the same machine, same account: claude --remote-control in tmux.
  3. Call ListAgents in each within the same minute.
  4. B enumerates A; A does not enumerate B, and A omits every 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.

dhollman contributor · 12 days ago

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 for ListAgents/SendMessage and 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.

Showing cached comments. Read the full discussion on GitHub ↗