SendMessage to a cloud session says "one-way for now … do not ask it to reply here", but the cloud session can reply via Remote send_message

Status Open
Reported on v2.1.286
Maintainer reply None cached
Activity 9 comments · opened Oct 2, 2026

Summary

When a local Claude Desktop (Code tab) session sends a message to a cloud session with the built-in SendMessage tool, the tool result says the route is one-way and tells the model not to ask for a reply:

… a Claude session running in the cloud; not confirmed read — that session may hold it (different permission mode: its user must approve first) or refuse it, and this route reports nothing back; one-way for now: a cloud session cannot message other sessions back yet — do not ask it to reply here; its response appears in its own transcript at claude.ai/code

In practice the cloud session can and does reply: it uses the Claude Code Remote MCP send_message tool, and the reply arrives in the local session as a normal user turn wrapped in <cross-session-message from-session="session_…">. So the instruction "do not ask it to reply" is misleading — models that follow it stop requesting replies that would in fact arrive, and they report the channel to the user as one-way.

Steps to reproduce

  1. Have a local Claude Desktop Code session (Remote Control connected) and a cloud session (claude.ai/code) on the same account.
  2. From the local session, call ListAgents, then SendMessage to the cloud session's name (listed with kind cloud).
  3. Observe the tool result text quoted above.
  4. In the cloud session, reply with the Claude Code Remote MCP send_message tool addressed to the local session.
  5. The reply is delivered to the local session as a user turn (<cross-session-message from-session="session_…">).

Observed

  • 2026-10-02 16:03 KST: local → cloud SendMessage returned the "one-way for now … do not ask it to reply here" text. At 16:04 the cloud session's reply arrived in the same local session as a user turn.
  • Same round trip observed several times between 2026-10-01 and 2026-10-02 across four different local sessions (the reply woke idle local sessions as well).
  • The wording caused repeated wrong conclusions: models wrote "cloud is one-way, do not attach reply requests" into shared instructions and reports, which then had to be corrected by hand.

Expected

The tool result should describe what is actually true, for example:

  • "A reply cannot come back over this same route; the cloud session can reply through its own Remote tools, and that reply will arrive here as a cross-session message", or
  • drop the "do not ask it to reply here" instruction when the target cloud session has the Remote send_message tool available.

Environment

  • Claude Code 2.1.286 inside the Claude desktop app (Code tab), Windows 11
  • Local session: Remote Control enabled; target: cloud session on the same account
  • Tools involved: built-in ListAgents / SendMessage (local → cloud), Claude Code Remote MCP send_message (cloud → local)

View original on GitHub ↗

9 Comments

uheira · 12 days ago

Follow-up from the same day, to keep the report accurate: the cloud → local direction is not reliable either.

  • 2026-10-02 16:37–16:5x KST: the cloud session sent three messages with the Claude Code Remote MCP send_message tool to a local Claude Desktop Code session (Remote Control connected, idle, same account). None of the three arrived in the local session's conversation. The target session_… id matched the local session's current (most recent) bridge session id.
  • Earlier the same day the same kind of message did arrive in other local sessions (including idle ones), as described above.
  • The sender got no failure signal; the miss was only found by reading the local session's transcript from the cloud side.

So there are two separate problems:

  1. The SendMessage tool result text says replies are impossible ("one-way for now … do not ask it to reply here"), which is wrong when delivery works.
  2. Cloud → local delivery via Remote send_message sometimes silently does not reach an idle local session, with no error on either side.

For (2), a delivery status the sender can check (delivered / queued / held for approval / dropped) would let sessions fall back to another channel instead of waiting.

uheira · 12 days ago

More detail on the cloud → local non-delivery, checked from the cloud side with the Remote session event listing (2026-10-02, times UTC):

  • Routing was correct. All five messages sent by the cloud session were attached to the local session's single live bridge session object (connected, idle, CLI 2.1.286) as events of type queued_notification, origin mcp_send_message, priority next — at 07:37:38, 07:43:46, 07:45:05, 08:02:13 and 08:16:09.
  • None of them was consumed: no dequeue/delivery event, no user event carrying the text, and the local session's turn was not woken. A ReadNotifications call in the local session two minutes after the fourth one returned "No queued notifications". On the local machine the text does not appear in any transcript file.
  • Earlier the same day (01:12:59, 01:29:24, 01:37:12 UTC) messages to the same local session — an earlier bridge object of it — were queued in exactly the same shape and were picked up by an assistant turn within 4–6 seconds, including one that woke an idle session.
  • One visible difference between the two periods: the capabilities listed in the session's init record. The working period shows ['queued_notifications'] (seen with CLI 2.1.284 and with 2.1.286 at 03:31 UTC); the non-working period shows ['queued_notifications', 'third_party_notification_caution'] (2.1.286, bridge object created 05:46 UTC).
  • In the other direction at the same time, a SendMessage from the local session to the cloud session was shown to the user in the app only as a "message received from another session" card and did not enter the cloud session's conversation.

So the messages are not lost or misrouted; they sit in the queue of the right session and are never handed to the conversation. If third_party_notification_caution is meant to hold third-party notifications for user confirmation, then (a) the sender gets no signal that the message is being held, (b) the receiving model cannot see or drain the held items (ReadNotifications reports none), and (c) it was not obvious on the local Desktop side that anything was waiting (whether a confirmation card was shown there has not been confirmed yet). Local-to-local messages between Desktop sessions on the same machine kept working normally during the same period.

uheira · 12 days ago

Follow-up: the user reports seeing no confirmation card or prompt for these queued third-party notifications in the receiving session's window (casual check, not exhaustive). So the notifications appear to stay queued without any visible surface to approve or read them.

uheira · 12 days ago

More data, narrowing this down: the problem is not specific to cloud → local. The affected local desktop session does not take in messages from another local session on the same machine either.

  • A local session called the desktop app's session-management send_message tool targeting the affected session while it was idle. Tool result: Message not delivered to session local_… : "that session gave no sign of starting on it within 20s (it may be waiting for approval there, or slow to start); it can still pick it up later". (delivery: undelivered).
  • Five seconds later the same sender used the same tool on a different local session: Message delivered … its turn has started on it. (delivery: delivered). So the sender and the tool work; only this one receiving session does not pick messages up.
  • The user confirms there was no approval card or prompt in either the sending or the receiving session window.
  • The message did not appear later either: the user sent a normal prompt to the affected session a few minutes afterwards, and neither that local message nor a cloud-session message queued around the same time entered the conversation. ReadNotifications in that session returned "No queued notifications."
  • The affected session is long-lived and has been through /clear many times (same session id, new conversation each time). Earlier the same day it received messages normally from both local and cloud senders; a fresh /clear did not restore delivery.

Desktop app on Windows 11, Claude Code 2.1.286.

uheira · 12 days ago

Root cause found on our side, correcting my previous comments: the receiving session was in bypass permissions mode. While a desktop session is in that mode, messages from other sessions (cloud send_message and local session-management send_message alike) are not taken into the conversation.

Evidence — per-turn permissionMode in the receiving session's transcript, matched against delivery:

| Receiving session mode | Inbound messages |
|---|---|
| auto (early afternoon) | 3 local messages delivered normally |
| bypassPermissions (about 4 hours, across a /clear) | 5 cloud messages + 1 local message: none delivered |
| switched back to auto | next cloud message delivered within seconds, as its own turn |

Details:

  • Sender side while the receiver is in bypass mode: local sender gets delivery: undelivered … gave no sign of starting on it within 20s (it may be waiting for approval there, or slow to start); cloud sender sees the message sit as queued_notification.
  • Receiver side: nothing visible. No approval card, no banner, and ReadNotifications returns "No queued notifications."
  • Messages sent during the bypass period did not arrive after switching back to auto; only messages sent afterwards did.
  • The third_party_notification_caution capability mentioned earlier was presumably just a consequence of this mode.

If blocking cross-session messages in bypass mode is intentional (it seems a reasonable safety choice), the gaps are in the surfaces:

  1. The sender's result could say the target is in a mode that does not accept cross-session messages, instead of "may be waiting for approval / slow to start".
  2. The receiving session's window could show that messages are being held, and whether they will be delivered or dropped when the mode changes.
  3. The original point of this issue still stands separately: the "one-way for now" wording in the SendMessage result.

Desktop app on Windows 11, Claude Code 2.1.286.

uheira · 12 days ago

One refinement to my previous comment. The SendMessage tool description already says: "a session running in a different permission mode than yours holds cross-session messages for its user's approval (and may let them expire)". So the condition is probably "sender and receiver are in different permission modes" rather than bypass mode specifically (I did not test bypass → bypass), and holding the messages looks intentional.

What remains is narrower: in the desktop app the receiving session's window showed no surface where the user could approve or even see the held messages (checked twice by the user), and the held messages were gone after the mode was switched back. So "held for its user's approval" was, in practice, a silent drop.

uheira · 12 days ago

Final correction after controlled tests (same machine, two desktop sessions, local session-management send_message, modes confirmed from each session's state file before every send). My "probably different permission modes" guess above was wrong.

| Sender → Receiver | Result |
|---|---|
| auto → auto | delivered |
| auto → default (manual) | delivered, no approval prompt for the message itself |
| bypass → bypass | delivered |
| auto → bypass | held (also cloud → bypass) |
| default → bypass | held |

So the only failing case we could find is: receiver in bypass permissions mode, sender not in bypass mode.

What "held" looks like on the receiving side (screenshots available if useful):

  • The session window shows a header line "Message received from <sender session>" and a small spinner, and nothing else. No approval card, no stop button; Esc does nothing.
  • Session management reports the session as idle (isRunning: false; stopping it returns "idle; nothing to stop"). The transcript has no record of the message.
  • Sender gets delivery: undelivered … gave no sign of starting on it within 20s (it may be waiting for approval there, or slow to start); it can still pick it up later.

Release / expiry:

  • Switching the receiver from bypass to auto released a message that had been held for about 2 minutes: it was delivered immediately as a normal turn.
  • Messages that had been held for 9 minutes or longer (up to ~2 hours) were not delivered after the same switch. We did not find the exact expiry time.

Requests, if holding in this case is intended:

  1. Give the receiving user something to act on (approve / dismiss) instead of a header and a spinner.
  2. Tell the sender the actual reason (receiver is in bypass mode and is holding the message), not "may be waiting for approval or slow to start".
  3. Document the rule; the current tool description ("a session running in a different permission mode than yours holds cross-session messages") does not match auto → default being delivered.

Desktop app on Windows 11, Claude Code 2.1.286.

uheira · 12 days ago

Correction to request 3 in my previous comment: the rule is documented, I just had not found it.

So this narrows to one defect plus two wording issues:

  1. Defect (desktop app): the docs say "When the default holds a message, Claude Code opens an approval dialog in the receiving session" with Approve / Deny. In the Claude Desktop Code tab no dialog appears: the receiving session shows only a "Message received from <sender>" header and a spinner, with nothing to approve, deny or stop, until the message silently expires.
  2. Wording (SendMessage tool description): "a session running in a different permission mode than yours holds cross-session messages" reads as per-mode, while the documented rule is per-class (auto → default is delivered).
  3. Wording (sender result): "may be waiting for approval there, or slow to start" could state that the receiver is holding the message under its inbound rule.

Plus the original item of this issue (the "one-way for now" wording).

kni927 · 12 days ago

Same wording observed on macOS, in a local Claude Desktop (Code tab) session that has Remote Control on — and the reply route the cloud session suggests is not available on the local side.

Environment

  • Claude desktop app, Code tab, macOS 26.6.2; claude CLI on PATH reports 2.1.287 (the desktop app's own version not checked separately)
  • Receiving/replying session: local, permission mode auto, Remote Control on (session management reports remoteControlActive: true, remoteControlState: "on")
  • Other side: a claude.ai/code cloud session on the same account

What happened

  1. The cloud session sent a task to the local session with its Remote send_message tool. It arrived as a cross-session-message with from-session="session_01…" and asked the receiver to reply by "calling the send_message tool of the Claude Code Remote MCP server with session_id set to the from-session value".
  2. The local session has no such MCP server. The two tools it has did not accept the cloud session id:
  • desktop session-management send_message with session_id: "session_01…" → Message not delivered: session session_01… not found. (delivery: undelivered)
  • SendMessage with to: "session_01…" → No agent named 'session_01…' is reachable. Use ListAgents to see everyone you can message.
  1. ListAgents listed the cloud session by name (<name> [ref] · cloud · idle). SendMessage to that name succeeded, but the result again said: "one-way for now: a cloud session cannot message other sessions back yet — do not ask it to reply here" — although this session is connected to Remote Control, which the docs say gives the message a reply address (https://code.claude.com/docs/en/cross-session-messaging#message-sessions-on-other-machines).
  2. Both messages sent this way (by name) did reach the cloud session; the user confirmed this in the cloud session. So local → cloud delivery works, and cloud → local had already worked in step 1 — the conversation is two-way in practice, which contradicts the "one-way" note.

Suggestions

  • Drop or condition the "one-way" sentence on the actual reply-address state, so the sender doesn't tell the receiver not to reply when a reply is possible.
  • Let a local session reply to the id it sees in from-session (or have SendMessage resolve it), or put the target's ListAgents name into the incoming envelope; today the reply instruction in the incoming message points to a tool that local sessions don't have.