Skip to content

Cross-session message delivered to transcript but receiving session never processes it #86319

Closed as duplicate

Description

@hornyt-ai

Environment

  • Claude Code version: 2.1.215
  • OS: Windows 11 Pro (native, PowerShell), not WSL2
  • Feature used: cross-session messaging via the session-manager tool exposed to Claude (send_message / list_events / list_sessions — the same feature surfaced in the UI as messaging between open Claude Code sessions)

Summary

A message sent from one session to another is written into the target session's transcript, and the target session's status flips to "running" (as if it were about to process the incoming turn), but the target session never actually generates an assistant turn in response — it never "reads" the message.

Steps to reproduce

  1. Open two Claude Code sessions locally (e.g. two tabs/windows in the session manager). Call them Session A (sender) and Session B (receiver). Session B was idle (isRunning: false).
  2. From Session A, send a message to Session B via the cross-session messaging tool, e.g.: send_message(session_id=<B>, message="Hola, te ha llegado el mensaje?").
  3. The tool call succeeds and reports the message was sent.
  4. From Session A, list Session B's recent events/transcript.

Expected

Session B receives the message as a new turn, Claude in Session B starts a new turn processing it, and (per the feature's own design) generates an assistant reply — the same way an interactive session responds to a new user message.

Actual

  • The message appears correctly in Session B's transcript as a user turn wrapped in a <cross-session-message from="..." name="..."> tag.
  • Session B's status changes from isRunning: false to "running" immediately after the message is delivered.
  • No assistant turn is ever produced in response. Two consecutive reads of Session B's transcript, several seconds apart, show the exact same last event (the incoming user message, with no reply after it).
  • This reproduced consistently in "todo tipo de sesiones" per the reporting user's own repeated testing before this specific repro (i.e. not isolated to one session or one type of session).

Notes

  • This is not the crossSessionInbound settings gate (accept/hold/refuse in settings.json) — that setting was already reviewed and doesn't explain this; the message is being delivered into the transcript (not held/refused), the receiving session just never actually processes the delivered turn.
  • Not an "unattended session" case (scheduled-task run / remote-dispatched session) — Session B was a normal local interactive session that was simply idle at the time.
  • This effectively breaks a common workflow: an orchestrator session coordinating multiple parallel worker sessions (e.g. across git worktrees) relies on being notified when a worker session finishes/reports back via cross-session messages; if the receiving session never processes the delivered message, the orchestrator never gets acted upon.

Activity

  1. arthurmoraesfernandes-afk commented on Aug 14, 2026

    @arthurmoraesfernandes-afk

    This looks like the "wedge" mechanism documented in the follow-up comment on #86298, with app-log evidence: an injected cross-session message that the CLI holds (consent gate) gets drained into the CLI at a turn boundary and is never "echoed" back as a user turn; the app then logs isRunning held by unechoed input at result … pendingEchoUuids: […] and treats the session as busy indefinitely — phantom turn, watchdog kills, and the user's own typed prompts queue/stall behind a turn that never ends until a priority=next send (typing another message force-flushes) or a restart reclaims it. Matches the delivered-to-transcript-but-no-turn state reported here.

  2. nourcosarl commented on Aug 14, 2026

    @nourcosarl

    One correction worth flagging, since this report and #86212 currently disagree on a detail that
    matters for debugging.

    This report says the message "is written into the target session's transcript". On this machine
    it is not — which matches #86212's finding instead.

    Environment: Windows 11 Pro 10.0.26200, Claude desktop 1.30096.1.0 (MSIX), bundled CLI 2.1.229.

    Measured directly rather than inferred: the recipient's .jsonl was polled across a send and
    for 150 s afterwards. Line count unchanged, no user turn, no message envelope. queue-operation
    entries in that same transcript did increase, so the send registered — the payload just never
    became a turn. Scanning every transcript on the machine finds no received envelope at all.

    The practical consequence, which cost us most of a morning: a transcript cannot be used to
    verify whether a cross-session message was delivered.
    We concluded messages "never arrived"
    because the transcript was empty, when they had in fact arrived and were visible on screen in
    the recipient's own window the entire time.

    Two other details from this machine, in case they help separate the variants:


    Correction to the above. I said the message is "not written" to the transcript. More
    precisely: there are zero confirmed genuine delivered peer turns from 2026-08-12 onward,
    after previously working. Before that date this machine recorded genuine wrapper-bearing user
    records daily — 247 on 08-11, 720 on 07-30, 3,748 in total across 2026-07-13 → 2026-08-11 (all
    dates UTC, from ISO-8601 Z transcript timestamps). 2026-08-12 has no wrapper-bearing user
    records of any kind. 2026-08-13 and 2026-08-14 contain 22 and 14 textual matches respectively,
    none of which classify as genuine deliveries — they are debugging artefacts quoting the
    wrapper.

    Classification used: user record, not a tool_result, <cross-session-message within the
    first 300 characters of message text.

    So both this report and #86212 describe the post-regression state rather than designed
    behaviour. The transcript write and the model-context injection are both absent in the verified
    post-regression samples, which suggests — but does not prove — a shared failed step. Last
    successful delivery here: 2026-08-11T23:48:54Z.

  3. hornyt-ai commented on Aug 14, 2026

    @hornyt-ai
    Author

    Re-tested on 2026-08-14 after updating to Claude Code 2.1.232 (from 2.1.215 where this was originally filed).

    Same repro steps as the original report: ccd_session_mgmt.send_message to a non-running local session, then ccd_session_mgmt.list_events on the target.

    Result -- unchanged:

    • The message is delivered and appears as a [user] turn with the <cross-session-message from="..." name="..."> wrapper.
    • The target session's status flips to "running".
    • No [assistant] turn is ever produced. Confirmed across three list_events reads spanning 20+ seconds.

    The 2.1.215->2.1.232 changelog has several "cross-session messaging" entries (2.1.224 "Cross-session SendMessage functionality enabled", 2.1.228 "Cross-session messaging initialization fixed", 2.1.232 "@ mentions reach other sessions via SendMessage"), but none of them affected this behavior -- this is on Windows 11 native (no WSL2), using the ccd_session_mgmt MCP tool layer, not the CLI-native cross-session messaging feature those entries likely refer to.

    Still open / still reproducible on 2.1.232, Windows 11 native.

  4. primrose0330-svg commented on Aug 14, 2026

    @primrose0330-svg

    Adding a data point that differs from the original report in one important way, and that I think narrows down where the fault is.

    Environment

    • Claude Code 2.1.201, Claude Desktop (MSIX package Claude_pzs8sxrjxfjjc)
    • Windows 11 Pro 10.0.26200.9168, native (not WSL2)
    • Tool: mcp__ccd_session_mgmt__send_message, sender is an interactive session, receivers are other local sessions

    What differs from the original report

    The original report says the message is written into the target's transcript but never processed. In my case the message is not written into the transcript at all while the target is dormant — and it is not lost either.

    Over two days I sent ~10 messages from one coordinating session to 5 dormant sessions. In every case:

    1. send_message returned Message sent to session <id> ("<title>").
    2. The target's .jsonl transcript gained no new user record. Record count stayed identical (verified by counting lines before and 20s after: 93 → 93).
    3. The transcript file's mtime sometimes advanced anyway, but the only records appended were metadata with no timestamp:
      assistant     <last real turn, 1-2 days old>
      last-prompt
      ai-title
      custom-title
      mode
      
    4. The target produced no output and made no progress.
    5. When a human typed anything into that session's tab, the pending message appeared immediately — carrying its original send timestamp, ahead of the human's own turn. Example: message sent at 20:55, human typed at 20:56, transcript then showed the sent message as a user record stamped 20:55, followed by a queue-operation record and the human's turn. The session then processed it normally and did the requested work.

    So the message is durably queued somewhere; what is missing is the wake. The receiving session is never scheduled to run, and nothing surfaces that state to the sender.

    Two different tool responses, only one of which is honest

    • Dormant target → Message sent to session <id> ("<title>").
    • Busy target → Message queued for session <id>; it will be processed after the in-flight turn finishes if that session stays healthy.

    The second is accurate. The first reports success for something that has not been delivered and will not be delivered until a human intervenes. For an agent coordinating other sessions this is the damaging part: there is no way to distinguish "delivered, being worked on" from "queued indefinitely", so the sender proceeds on a false premise. I spent two days concluding sessions were dead when they were simply never woken, and re-derived that wrong conclusion twice because the transcript genuinely shows no incoming message.

    Suggestions

    • Have send_message report the target's state, e.g. Message queued; target session is not running and will process it when next resumed — this alone would remove most of the harm even if the wake is not implemented.
    • If waking a dormant session is out of scope, saying so in the tool description would be enough; the current wording implies delivery.

    Workaround for anyone hitting this

    Coordinate through the filesystem instead. Writing the request as a file in the target's working directory and committing it worked reliably — a scheduled/unattended run in that repo picked it up and acted on it without any session being woken.

  5. bcherny commented on Aug 15, 2026

    @bcherny
    Collaborator

    Closing as a duplicate of #86212 — please follow and 👍 that issue instead so we can track it in one place. If you think this was closed in error, comment here and we'll reopen.

    🤖 Generated with Claude Code

  6. github-actions commented on Oct 1, 2026

    @github-actions

    This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.

  7. locked as resolved and limited conversation to collaborators on Oct 1, 2026
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

    area:agentsduplicateThis issue or pull request already existsplatform:windowsIssue specifically occurs on Windows

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions