Skip to content

Cross-session messages are delivered but never trigger the recipient's turn (desktop app, Windows) #86212

Description

@DensCad

Bug report — cross-session messages are delivered but never trigger the recipient's turn (Claude Code desktop, Windows)

Summary

mcp__ccd_session_mgmt__send_message reports Message sent to session ..., and the message
is genuinely delivered — it appears in the recipient's queue via list_events and renders
correctly in the recipient's window. But it does not cause the recipient session to run a
turn
. The recipient stays idle indefinitely (measured at 0.4% CPU). The message is only
processed once a human types something — anything — into the recipient's window.

There is no error, no notice, and no timeout. From the sender's side it is indistinguishable
from a broken channel, which is what sent us down three wrong diagnoses before we measured it.

Environment

OS Windows 11 Home 10.0.26200
Claude Code 2.1.227, entrypoint: "claude-desktop" (read from ~/.claude/sessions/<pid>.json)
CLI on PATH 2.1.226 (~/.local/share/claude/versions/2.1.226) — a separate install, not the one running the sessions
Sessions 9 local sessions across 8 project folders, all in permission mode "normal"
Transport MCP server ccd_session_mgmt (list_sessions, send_message, list_events)
Date of measurements 2026-08-12, ~22:28–22:40 local (UTC+2)

Steps to reproduce

  1. Open two Claude Code desktop sessions, A and B, in different project folders, both in
    permission mode normal.
  2. From A, call mcp__ccd_session_mgmt__send_message with B's session_id.
  3. Tool returns Message sent to session <id> ("<title>").
  4. Do not touch B's window.

Expected

B processes the incoming message and runs a turn (this is what the sender's tool description
implies: "The message arrives in the target session as a user turn").

Actual

B does nothing, with no indication that anything is pending on its side beyond the rendered
message. It stays idle indefinitely.

Confirming step

Type anything into B's window (we used the single word vas-y). B immediately runs a turn and
correctly processes every queued message, including ones that had been waiting for hours.

Measurements

Recipient is idle, not busy or hung. Two CPU samples of the recipient process, taken 15 s
apart while a message sat in its queue, versus the sender doing normal work:

recipient (pid 6372) : 5.859s -> 5.922s   delta = 0.06s over 15s   (0.4%)
sender    (pid 13340): 21.64s -> 22.56s   delta = 0.92s over 15s   (6%)

Queue holds, nothing fires. Two messages sent to the same recipient sat unprocessed for
about 6 hours and about 8 minutes respectively. Both were visible the whole time via
list_events against that session, with correct content and intact accented characters.

A single keystroke releases everything. The recipient's transcript records the user prompt
vas-y at 2026-08-12T20:36:59.471Z. The turn started immediately and the model's reply
quoted and acted on both queued messages.

Second, possibly separate issue: received messages are never written to the transcript

Received cross-session messages are never persisted to the recipient's .jsonl transcript
— not while queued, not while being processed, not after the turn completes successfully.

  • Scanned all 9 transcripts under ~/.claude/projects/*/: zero received envelopes.
  • In the turn described above, the model demonstrably read and acted on two queued messages;
    the transcript records only the typed prompt vas-y.

Two consequences that actively mislead debugging:

  1. A transcript cannot be used to verify that a message was received, even for messages
    that were received and fully acted upon.
  2. The list_events message count decreases when queued messages are dropped (we observed
    335 -> 334 on one session). This reads as data loss. One of our sessions concluded from it
    that messages were "delivered then removed without being processed", and built a whole
    causal story on that number.

What we ruled out

hypothesis how it was eliminated
Version mismatch between sessions All ~/.claude/sessions/*.json report 2.1.227 (one dead process at 2.1.222). Note: claude --version returns 2.1.226 because it queries the PATH CLI, not the desktop binary — this is itself a trap for anyone diagnosing.
HTML-entity encoding of the body (encoded="1") The message renders fully decoded in the recipient's window, accents intact (screenshot available).
crossSessionInbound holding messages for approval That setting only applies to a recipient running with bypassed permissions. All 9 sessions measured in mode "normal"; the key is absent from ~/.claude/settings.json.
Recipient blocked on a permission prompt No dialog present, and typing an unrelated word releases the turn — a pending permission request would not be satisfied that way.
Recipient hung on MCP server startup The recipient had a npx @playwright/mcp@latest child still starting; so did the sender, which was working normally.

Possibly related changelog entries

  • 2.1.225 — "Fixed cross-session messages staying parked without a notice or expiry in
    headless sessions and during startup"
    . "Parked" is exactly our symptom, and our messages
    arrived shortly after the recipient restarted (recipient process start 22:28:53, message
    sent ~22:30). Our sessions are interactive, not headless.
  • 2.1.224 — "Added cross-session SendMessage ... (macOS and Linux)". We are on Windows
    and using the desktop app's ccd_session_mgmt MCP tools, which may be a different mechanism
    from the CLI's SendMessage. We flag this as a lead, not a claim.

Questions

  1. Is "delivered but does not trigger a turn" the intended behavior for cross-session messaging
    in the desktop app on Windows? If so, the sender's tool result (Message sent) and its
    description ("arrives in the target session as a user turn") both suggest otherwise, and a
    sender has no way to learn that the message is parked.
  2. If this is the "parked" condition fixed in 2.1.225, should it also apply to interactive
    sessions outside startup?
  3. Is the non-persistence of received messages in the recipient's transcript intended? If so,
    could the docs say it explicitly? It currently makes transcripts look like evidence of
    non-delivery.

Unexplained, no reproduction — reported for completeness

Earlier the same day (around 16:00–16:50 local), the user observed four recipient sessions
showing a turn in error shortly after receiving a message from one particular sender
session. We could not reproduce this, and could not identify a cause: it is not the version
(no gap exists), not the encoding, and the same sender's later messages completed normally.
We mention it only in case it matches a known signature; we are not claiming a link.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleIssue is inactive

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions