[BUG] Windows/MSIX 1.28929.0: cross-session messages land in the target's composer but are never submitted — session never responds
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
On Windows (MSIX/Store install), send_message between Claude Code sessions reports success and the message visibly appears in the target session's input composer — but it is never submitted. The target never produces a turn. Observed sitting unprocessed for 39+ minutes.
Typing the identical text into that same session by hand works instantly, so the target session is healthy. Only the delivered message fails to execute.
Two additional findings:
- Queued messages OVERWRITE each other. Sending a second message to a session with one still unprocessed replaces it — the first is lost silently with no notice. Messages can disappear entirely.
- In the target's transcript JSONL the message is written as a
last-promptrecord, never as atype: "user"turn. It is stored as a pending prompt rather than enqueued.
This worked reliably until 2026-08-11 ~18:48 ET and has failed 100% since.
What Should Happen?
The target session should process the delivered message as a conversation turn and respond, as it did prior to 2026-08-11.
Error Messages/Logs
No error is produced anywhere. The tool returns:
Message sent to session local_<id> ("Flow HQ").
The message renders correctly in the target session UI. Nothing fails loudly — it simply never executes.
Delivery counts across six long-running sessions, cross-session messages processed as real turns vs parked:
Session A: 45 processed, 0 parked
Session B: 30 processed, 0 parked
Session C: 23 processed, 0 parked
Session D: 21 processed, 0 parked
Session E: 6 processed, 0 parked
Session F: 3 processed, 0 parked
128 successful deliveries, zero failures, through 2026-08-11 18:48 ET.
Since 2026-08-12 07:54 ET: 17 sends, 0 processed. Every one returned success.
Steps to Reproduce
- Open two Claude Code sessions, A and B, on Windows (MSIX/Store install).
- From session A, call send_message targeting session B.
- Tool returns: Message sent to session <id> ("B").
- Open session B — the message is visibly present as a "Message from A" block.
- Session B never processes it. No assistant turn is ever generated.
- Type any text into B by hand — it responds immediately.
Ruled out during diagnosis:
- Privacy/telemetry env vars (CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, DISABLE_TELEMETRY, DO_NOT_TRACK, DISABLE_GROWTHBOOK) — all unset at process, user and machine scope
- Windows Firewall — all Claude inbound/outbound rules present, enabled, action Allow
- Stale process state — reproduces after a full quit (all processes killed and verified) and relaunch
- Orphaned pre-existing sessions — reproduces in a session created minutes ago, after the failure began
Change window: four changes landed between the last success (8/11 18:48) and the first failure (8/12 07:54):
- Claude 1.28929.0.0 installed 8/11 21:10 — its release notes mention fixing MSIX installs "failing to save chat history, settings, and scheduled tasks," so this build touched MSIX persistence
- KB5123304 (8/11), KB5121003 and KB5120708 (8/12)
I cannot isolate which. Flagging the MSIX persistence change as most suspicious given the install type and the symptom: a prompt that is stored but never enqueued.
Possibly related: the 2026-08-08 fix for "cross-session messages staying parked without a notice or expiry" — same class of parking, reappearing after 8/11.
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
unknown — the build immediately prior to 1.28929.0.0 (MSIX update removed the old package folder). Last confirmed working 2026-08-11 18:48 ET.
Claude Code Version
1.28929.0.0
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
_No response_
39 Comments
I am seeing it on the same version.
Also confirming the silent overwrite — a second message to a session with one still pending replaces it with no error. Running seven sessions, this loses messages invisibly.
oh my EFFING GOD. I HAVE BEEN TRYING TO DEBUG MY PLUGIN for 2 whole days, thinking it was one of the INTERRUPT COMMANDS i created (which predates the actual new interrupt commands that just got into the desktop app), then i thought it was because of the MESSAGE CONTRACT structure and the new tags i created for this architecture... (note, i've been making sessions communicate with each other for 2 weeks, way before it was announced since it was probably shadow released and I accidentally discovered this)
my claude wanted to say "Confirming on Windows 11, Claude Desktop 1.28929.0 — same build as OP.
Reproduced twice, four sessions in four empty directories, no plugins/hooks/project settings:
Message sent, recipient'slastActivityAtupdates, card renders in its UIgrep -c 'cross-session-message'→ 0 on the receiver, 59 on a transcript known tocarry them (control, same pattern, so the zero isn't a blind matcher)
Ruled out here:
crossSessionInbound: "accept", every user-scope plugin and marketplace disabled,full app restart, recipient both idle and actively prompted.
⚠ One trap for anyone testing this:
claude --versionis not the version that runs. Desktopembeds its own build. Mine reports
"version":"2.1.227"in the transcript rows while the PATH CLIwas 2.1.226, then 2.1.231 after
claude update— which does not touch the embedded one. Read the"version"field in~/.claude/projects/<key>/<session>.jsonlinstead."i hope someone will realize and fix this ASAP, i already sent my own personal bug reports.
Same issue here. Windows 11 Pro (build 26200), MSIX/Store install 1.28929.0.0.
Confirming identical behavior across ~12 local sessions since Aug 12: send_message returns success, the message renders in the target session, but no turn ever starts. Typing the same text manually works instantly.
One extra data point from Roaming/Claude/logs/main.log: when a message arrives, the target session IS resumed ("Resuming session ..." + "Loaded N transcript messages" + PTY start), but no "[CCD start-timing]" line ever follows — the wake-up happens, the enqueue doesn't. Also: the bundled CCD updating 2.1.222 → 2.1.227 on Aug 13 changed nothing, which points at the app/MSIX layer rather than the CLI.
Can also confirm the silent-overwrite behavior: a later message replaces the parked one (the transcript's trailing "last-prompt" record gets swapped, the first message is gone).
Independent confirmation on a separate machine, plus one data point that may narrow the regression window.
Environment
Claude (MSIX/Store) 1.28929.0.0
claude-code CLI 2.1.227 (was 2.1.222 before)
OS Windows 10 22H2 (19042)
Symptoms match this issue exactly — send_message returns success, the text appears in the target
session's composer, the target never produces a turn, and typing the same text by hand works
instantly. Confirmed visually on two separate occasions by watching the target window.
1. The regression appears to trigger on the first app restart after the MSIX update, not on the update itself
This is the part I have not seen in the thread, and it may explain why different reporters give
different "last working" timestamps.
2026-08-12 10:26:55 KST MSIX manifest mtime (package updated to 1.28929.0.0)
2026-08-13 09:52:40 KST ★ last successful cross-session delivery
2026-08-13 10:04:05 KST app process restart (all Claude.exe PIDs replaced)
2026-08-13 10:04:06 KST claude-code 2.1.227 downloaded
2026-08-13 12:30 KST → ★ 100% failure from here on
So the package was already at 1.28929.0.0 for roughly 23 hours while cross-session messaging still
worked normally (15 successful deliveries in that window). It broke only after the app was restarted
and the new binaries actually took effect.
If that generalises, the useful boundary for bisecting is "first launch on 1.28929.0.0", not "time
of MSIX install".
2. Not related to session size, age, or state
I initially suspected a large/old session. That is ruled out:
Old session 53 MB transcript, 73 days old → fails
New session 404 KB transcript, minutes old → ★ fails identically
A brand-new session created specifically to replace the old one reproduced the failure on its first
incoming cross-session message.
3. Additional remedies tried, all ineffective
/compact no effect
ESC (interrupt) stops the spinner, queue still not drained
archive → unarchive no effect
full app quit from tray + relaunch no effect
replacing the session entirely no effect (see §2)
mixed CLI versions unified to 2.1.227 no effect
Notably, after the app restart two claude-code 2.1.222 worker processes kept running alongside
2.1.227 ones. Unifying everything to 2.1.227 changed nothing, so the CLI version mix is not the
cause — consistent with this being an app-layer (MSIX) regression.
4. Direct operator input into the same session works throughout
Over the same period the affected sessions answered 23 typed prompts in 5–37 s each, while 10
consecutive cross-session messages were never turned into a turn. The sessions themselves are
healthy; only the queue-to-turn path is broken.
5. Practical note on the overwrite behaviour
The overwrite behaviour mentioned in the issue body caused real damage here: a "resend" of three
pending requests very likely destroyed the two earlier ones, so the recipient had no copy of any of
them. For anyone working around this — do not resend. Put multiple items into a single file and send
only the path, or hand the content to the recipient window directly.
6. Current workaround
Nothing else got a message through.
Message sentfrom the tool carries no information aboutdelivery or processing, so it cannot be used as an acknowledgement.
Composer-level arrival, never submitted — #86298 documents the same failure chain with root-cause analysis (Windows desktop, regression at app 1.28929.0 / bundled CLI 2.1.227, still present on app 1.30096.1.0 / CLI 2.1.229): the desktop bridge sends the message with a class-less
origin:{kind:'peer'}, the recipient CLI/SDK's cross-session consent gate holds it for an approval no desktop surface offers, anddialogExpiry(~5 min) then drops it — while the sender keeps a success receipt. A memory-dump repro in that thread shows the payload reaching the recipient CLI process but never its transcript. SettingcrossSessionInbound: "accept"in user settings does not unblock it (tested on running, cold-started, and post-restart fresh sessions).Still reproduces on 1.30096.1.
Environment
Claude (MSIX/Store) 1.30096.1.0 (was 1.28929.0.0)
claude-code CLI 2.1.229 (single version, no mix)
OS Windows 10 22H2 (19042)
Restart was thorough — closed all windows, quit from the tray, then killed every remaining
claude.exefrom Task Manager before relaunching. Package version and CLI version both confirmedchanged afterwards.
Result: identical to 1.28929.0.
target session OPEN message appears in composer, never submitted, no turn produced
target session STOPPED message does not appear at all
One clarification to my earlier report: "the message appears in the composer" holds only for
sessions that are open. For sessions that were stopped (killed in Task Manager before the
restart), the message does not surface at all. I have not verified whether it appears when those
sessions are later reopened, so I can't say whether it is queued-but-hidden or dropped.
Current workaround unchanged — we route everything through files on disk plus a background
watcher per session, and a scheduled task that mirrors a remote mailbox into that shared folder.
That path is unaffected by this bug and has been running for ~12 hours without a miss.
Two observations that I don't think are in the report yet — both change the impact, not just the symptom.
1. The receiving session becomes unusable, not merely unresponsive.
After a cross-session message lands, the target shows a running spinner and stays there. In one
case it sat for 35 minutes; CPU for that session's CLI process was ~0 the whole time, so it is not
working, it is stuck. The session cannot do anything else until a human types into it. So the
blast radius is larger than "the message is lost" — one delivery attempt can park a working
session indefinitely.
2. The session cannot see the message content at all.
We asked a stuck session to "check your messages". It ignored the text sitting in its own composer
and read only the files we had put on a shared folder. So what appears in the composer is visible
to the human but is not part of the model's input. This also explains why an earlier session told
us it had "received nothing" while the text was plainly on screen — it genuinely could not see it.
Practical consequence for anyone working around this: relaying the content by hand does not help
if you paste it into the same composer. Put the content in a file and type only the path into the
target session. That works immediately.
Confirming on Windows 11 Pro 26200, Claude Desktop 1.28929.0.0 (MSIX/Store), embedded CLI 2.1.227. 3 cross-session sends today, 0 delivered.
One log signature I have not seen posted yet — it isolates the exact step that is skipped. In
Roaming/Claude/logs/main.log, a human-typed message always produces TWO lines:A cross-session message produces ONLY the second:
Today's log has exactly 3 such orphan
Sendinglines with no precedingLocalSessions.sendMessage— and all 3 are cross-session messages. All 11 human-typed messages in the same window have both lines. Clean discriminator, no false positives either way.Downstream effect, same log:
Every other cycle that day logs
hadFirstResponse=true. So the delivery does wake the target and open a turn — the turn just never receives content, which is the spinner users are seeing.Confirming the unstick behaviour: the third orphan send (10:40:12) produced no stalled cycle, because the operator typed into that session 15 s later. That message logged
priority=nextand took over the parked cycle immediately. So a human-typed message reliably clears the stuck spinner.Also confirming: the receiving model cannot see the composer text at all. Its transcript has no record of either message — not as a turn, and not as a trailing
last-promptrecord.Another Windows/MSIX confirmation, but the reason I'm posting is a longitudinal count of the recipient-side stall from
main.log, with a clean pre-regression baseline. I haven't seen the impact quantified over time in this thread yet.Setup
send_messageRecipient stalls per day
Counting
[CCD CycleHealth] unhealthy cycle for <session> (…, hadFirstResponse=false, reason=no_response)— i.e. the recipient opened a turn, never received content, and was killed by the inactivity timeout at ~1000 s:| Date | Stalls |
|---|---|
| 2026-08-01 | 2 |
| 2026-08-02 … 2026-08-11 | 0 |
| 2026-08-12 | 15 |
| 2026-08-13 | 25 |
| 2026-08-14 (partial day) | 9 |
51 total, across 18 distinct sessions. Ten consecutive days at zero immediately before the onset.
Every stall is
reason=no_responsewith an inactivity timeout in the 960–1020 s range, matching the "spinner with ~0 CPU until the watchdog" behaviour others have described here. On 2026-08-14 08:41:09 six sessions timed out within the same second, all at ~1000 s — a single burst of sends parked six working sessions at once.Delivery, paired by runtime version
Separately, pairing each send with whether the recipient produced a turn:
And counting only deliveries that started a turn with no human input, partitioned by the runtime recorded in the transcript rows:
| Runtime | Auto-started turns |
|---|---|
| 2.1.202 – 2.1.222 (8 versions) | 3,613 |
| 2.1.227 | 0 |
| 2.1.229 | 0 |
Prior-behaviour control: one long-running session in July received 145 cross-session messages and 145 of them started a turn on their own, median 12.7 s from delivery to first output (min 2.9 s, max 46.1 s), none requiring a keystroke.
What I can't separate, and a correction to my own first read
I initially thought this machine could isolate app build from runtime version, because the app was at 1.28929.0.0 from 10:17 local while sends kept working until 12:43, and the runtime flipped 2.1.222 → 2.1.227 at 13:46–13:53 with the first failure at 13:59. But @woonis-locuss's "it triggers on the first app restart after the MSIX update, not on the update itself" explains the same data at least as well — the restart and the runtime switch coincide here. So I don't think my timeline distinguishes the two, and I'm withdrawing that reading rather than adding a fourth theory to the thread.
Current state
Still reproduces on 1.30096.1.0 / 2.1.229, consistent with #86557 and #86298.
Practical note that matches what others found: the failure is not benign for the sender's counterpart. A single
send_messagecan park a healthy session for ~17 minutes. Once we understood that, we stopped usingsend_messageentirely and moved all inter-session traffic to an append-only file on disk plus a per-session startup/prompt hook that injects unread items into context. That path has been unaffected. It looks like several people here converged on the same shape independently.One diagnostic caveat for anyone measuring this: grepping the recipient's transcript will report zero deliveries even when the message arrived, because it is written as a
last-promptrecord rather than atype: "user"turn. I lost about a day to that before switching to themain.logcycle-health lines, which do record it.Same failure on macOS — this is not Windows/MSIX-specific
Adding a data point because the
platform:windowslabel may be causing this to be scoped too narrowly. We hit the identical signature on macOS.Environment
Symptom — matches this issue exactly
send_messagetargeting session B. The tool returns success:Message sent to session local_… ("<B's title>").One extra piece of evidence that may help localize it
I embedded a unique token (
ECHO-0814-A7) in the message body specifically so it could be traced. A grep for that token across every transcript JSONL under~/.claude/projects/matched exactly one file — the sender's own transcript. It is not present in any other transcript on disk.So on macOS as well, the message is delivered to the target's UI/session layer but never lands in the target's transcript as a real user turn. That is consistent with the "stored as a pending prompt rather than enqueued as a turn" mechanism described in the original report. (
type: "last-prompt"records do exist in our transcripts, so that record type is in play on macOS too — I did not confirm that this specific message was written as one.)Why the "queued messages overwrite each other" part matters a lot
The day before, we assumed we were losing messages — we counted "≥5 dropped" across several sessions and made an operational decision based on "the channel drops messages." Given the overwrite behaviour described here, it seems likely most of those were not drops at all: later messages silently replaced earlier unprocessed ones. Two very different failure modes that look the same from the outside, and the silent-overwrite one is the more dangerous of the pair.
Impact for us
We run a multi-session workflow where sessions hand work to each other. Because the send call reports success and the message is visibly delivered, there is no signal available to the sender that the work was never picked up — it looks delivered from every angle we can observe. We have had to fall back to routing all cross-session coordination through issue cards and treating messages as best-effort only.
Happy to provide more detail (redacted transcripts, timings) if that's useful.
Two small follow-ups, one of which may matter for the regression window.
@Qin-C — worth double-checking which version that is
Your report is on macOS with Claude Code 2.1.220, which would put the onset earlier than the 2.1.222 → 2.1.227 boundary several of us measured. Before that reshapes the window, @TomerBrosh's caveat earlier in this thread is worth applying:
On this machine the two disagreed by several releases. If your 2.1.220 came from the CLI on
PATHrather than from the transcript rows, the embedded runtime may well have been a later build — in which case the window is unchanged. If it came from the transcript rows, that's a genuinely earlier onset and worth flagging loudly.Either way, your macOS reproduction with the token-grep result stands on its own, and the
platform:windowslabel does look too narrow.crossSessionInbound: "accept"— corroborating that it does not help, at production scale@arthurmoraesfernandes-afk already established this with probe sends in #86298. Adding a larger sample from continuous use rather than probes:
"crossSessionInbound": "accept"present in user-scope settings from 2026-08-13 18:26 at the latest (confirmed in three independent copies of the file)reason=no_response, all in the 960–1020 s rangeSo the key is not merely ignored for already-running recipients; it stays ineffective across hundreds of fresh processes and several full app restarts. Same conclusion as the probe test, from a different sampling method.
Follow-up to my macOS report: a positive case, and a confirmed silent-overwrite timeline
Correcting/sharpening my earlier comment. I implied delivered messages never execute. That's too strong — on the same machine, same day, a cross-session message was received and executed normally. The difference between the two cases looks diagnostic, so here is the pair:
| | Case A (failed) | Case B (worked) |
|---|---|---|
| Sent at | 06:27 UTC | 08:48 UTC |
| Target's state when sent | idle for ~2 days | mid-run, about to finish a turn |
| Outcome | never appeared in target's transcript | delivered and executed — target acted on it |
The part that pins down the overwrite behaviour:
The target in Case A did wake up later and run 35 turns (opened a PR, merged it, sent its own messages) roughly two hours after my message. My unique token
ECHO-0814-A7appears in none of those turns — a grep across all transcripts still matches only the sender's own file.So the message sat in that session's input box from 06:27, and the prompt that eventually woke the session replaced it. It never became a turn and left no trace anywhere. That matches the "queued messages overwrite each other" behaviour described upstream in this issue, now with a concrete timeline rather than inference.
Suggested reading of the two cases together
Delivery appears reliable. What's missing is that delivery does not trigger a turn — the message is only picked up at the target's next turn boundary, if one happens before something else overwrites the box. That would explain both cases exactly:
If that reading is right, the observable symptom scales with how idle the target is, which may be why this looks intermittent and hard to reproduce on demand — and it means the worst-hit use case is precisely "hand work to an idle session," where the sender has no way to tell the difference between "picked up" and "silently discarded."
Environment unchanged from my previous comment (macOS 26.6.1, Claude Code 2.1.220, desktop).
@Qin-C — the A/B contrast is useful, and the overwrite timeline is real progress. One part of the proposed reading doesn’t match what this machine logs, and the difference changes where the fix would go.
Delivery appears reliable. What’s missing is that delivery does not trigger a turn
On Windows here, delivery does trigger a turn. The turn opens and then starves.
Pairing individual sends to individual recipient stalls
From main.log, pairing each Sending message to session <id> against a later [CCD CycleHealth] unhealthy cycle for <same id> (…, hadFirstResponse=false, reason=no_response):
• 28 of 51 stalls had a send to that same target inside the preceding 20 minutes
• send → stall-logged lag: median 1005 s (min 2 s, max 1130 s)
The inactivity timeout that produces those lines is ~1000 s. A median lag of 1005 s means the cycle opened essentially at the send and was killed one timeout later — not that it never opened. This matches @Bruno-1728’s correlation earlier in this thread (“the delivery does wake the target and open a turn — the turn just never receives content”).
Send volume was not the variable
Same log source, per day. Sends here are roughly constant across the regression boundary while stalls are not:
Date Sends Recipient stalls
2026-08-08 202 0
2026-08-09 230 0
2026-08-10 99 0
2026-08-11 508 0
2026-08-12 167 15
2026-08-13 34 25
2026-08-14 16 9
508 sends produced zero stalls the day before; 34 sends produced 25 the day after.
Why the distinction matters
If delivery never opened a turn, the target would simply sit idle and the message would wait for the next boundary — annoying, but the session stays usable, and your Case B falls out naturally. What we see instead is that the opened turn holds the session for the full watchdog window, so one send costs the recipient ~17 minutes of availability whether or not the message is ever seen. That makes the repair target the hand-off after the turn opens, not the wake itself.
Your Case A/B split may still hold on macOS — if delivery there genuinely doesn’t open a cycle, that is itself a platform difference worth recording, and main.log’s CycleHealth lines would show it either way.
Caveats
• The send/stall pairing is a log-line heuristic, not an instrumented trace; 23 of 51 stalls had no send inside the window and I can’t attribute those.
• Windows/MSIX here; your reports are macOS.
guys dont waste tokens on coordination/communication now... i had to park all this in my plugin and there is no point in trying to create loopholes for something that hopefully will be fixed within a week.
The thing that annoys me is that their official doc and Fin helper agent said that this doesnt work in Windows, which is clearly a lie or misdirect from anthropic's official docs...
+this was working for 2 weeks BEFORE they announced that capability, and now users will just think "ah, it doesnt work on windows thats why it is stuck" and wont report the bugs...
_IF U MUST COMMUNICATE IN ORDER TO CLEAR DIRTY FILES, have the agents give u a copypastable u can use to manually paste messages until they fix this_. (sadly i was mid creating a whole architecture for coordination and thats half of my agents' checklist)
Second reporter, independent environment. Same platform class (Windows 11 / MSIX Store install). Evidence below is taken from my own
~/.claude/projects/**/*.jsonltranscripts, matching eachmcp__ccd_session_mgmt__send_messagetool_use on the sender side against the receiving session's records.Confirming the failure on 2026-08-12
Two sends to an idle target session produced no record at all on the receiving side — no
queue-operation, notype: "user"turn, nothing:| sent (local time) | target | result on receiver |
|---|---|---|
| 08-12 08:28:01 |
local_6f69bb01…| nothing || 08-12 09:22:07 (manual resend) |
local_6f69bb01…| nothing |The target session was active again later the same day (last activity 08-12 18:19), so this is not "never reopened" — the messages were lost. Both sends returned success. My transcript from that day literally contains the sender writing "再送も着信しませんでした" ("the resend didn't arrive either"), so this was noticed live, independently of this issue.
Current build: delivery restored, but latency is unbounded
On
Claude 1.30096.1.0(CLI 2.1.212) all three sends on 2026-08-14 did land, asqueue-operationfollowed by atype: "user"turn:| sent | delivered as user turn | delay |
|---|---|---|
| 08-14 09:48:39 | 09:51:56 | ~3 min |
| 08-14 11:32:29 | 11:33:27 | ~1 min |
| 08-14 11:45:44 | 12:14:55 | ~29 min |
So the total-loss symptom appears fixed in 1.30096.1.0, but a delivered message is not processed until the target session is next attended to. From the sender's side this is indistinguishable from the original bug — the tool returns success and nothing happens for an arbitrarily long time. Worth considering as part of the same fix: either the sender's tool result should say "queued, target busy/idle" rather than a bare success, or the target should be woken.
I have not re-tested the message-overwrite behaviour on the current build.
@Kie610 — same app build here, opposite result. Posting it because "fixed in 1.30096.1.0" would leave environments like this one behind if it becomes the thread's conclusion.
Same build, 0 of 5 landed
Windows 11 / MSIX, desktop 1.30096.1.0, bundled runtime 2.1.229.
On 2026-08-14, one session sent five cross-session messages between 10:40:31 and 10:41:37, one to each of five other local sessions. Ten hours later, none of the five has appeared in its recipient's transcript — not as a
type: "user"turn, not at all. Three of the five recipients were opened and worked in by a human within ~15 minutes of the send, so this is not "never attended".Method, because a negative claim needs one
Each of the five messages had different body text, so each recipient has a unique probe string. For each recipient I searched its own transcript only, keeping a row only if all of these held:
typeisusertoolUseResult/tool_use_id(excludes the string appearing in some tool's output)Result: 0 / 5.
Control, run with the identical filter: a cross-session message sent on 2026-07-08 is found in its recipient's transcript at 07-08 18:31:14. So the search is not silently broken — it finds landings when they exist.
That control matters. My first pass at this returned false positives: the probe strings matched my own investigation output sitting in my own transcript. Anyone measuring this should exclude tool-output rows and verify the method against a known-good delivery before trusting a zero.
What that implies
Your three sends landed with 1–29 minute delays; five sends here have not landed in ten hours. Same app build. So the build is not the only variable, and "delivery restored in 1.30096.1.0" doesn't generalise. Something else differs — permission-mode class, settings scope, session count, or how long the recipients had been idle.
Minor: the version number
You list CLI 2.1.212, which predates the 2.1.222 → 2.1.227 boundary in this thread — and predates cross-session
SendMessageshipping in 2.1.224. That's the second report in this thread with a runtime version that looks like the one fromPATHrather than the embedded one. @TomerBrosh flagged this earlier:Worth confirming from the transcript rows before the reported versions are used to bound the regression.
@TENNONKI Thank you for the corrections — all four points are right and I was wrong. I retract "delivery restored in 1.30096.1.0".
Version (your last point) — correct, the 2.1.212 I posted was the
PATHCLI. Read from theversionfield in the transcript rows, this machine actually ran 2.1.227 → 2.1.229 (app 1.30096.1.0). You are also right that 2.1.212 predates SendMessage shipping, so that number cannot be used to bound the regression window.On "same build, different result → something else differs" — it was a measurement error on my side, not a difference in variables. In
main.log, all three of my turns were me submitting the composer text by hand: each turn is preceded byLocalSessions.setFocusedSession(opening the session) 45s / 25s / 11s earlier, followed byLocalSessions.sendMessage. At the actual send times there is noLocalSessions.sendMessageat all — two show only an orphanSending message to session, one shows onlyResuming sessionwith no send line. Corrected result: 0 of 3, same as your 0 of 5.One addition to your method caveats — my three rows passed your strict filter (
type: "user", notoolUseResult/tool_use_id, timestamp after the send, probe near the start of the row). They passed and the conclusion was still wrong, because a landed user turn does not prove auto-delivery — a human submitting from the composer produces an identical row. The extra step that catches this is checkingmain.logfor asetFocusedSession→LocalSessions.sendMessagepair immediately before the turn.messageLengthequals the character count of the resulting turn body (4204 / 2842 / 3233 in my case), so the pairing is easy to confirm.One more trap, the direct cause of my misreading — transcript
timestampis UTC,main.logis local time. I compared transcript against transcript only and read the gap as "1–29 min delivery latency". That interval was actually how long the message sat parked in the composer, and its end was my keystroke, not a delivery. Convert one side before pairing them (+9 here).Sorry for the noise.
Independent corroboration on Windows, different build — this is not fixed by the 1.30096.1.0 / CLI 2.1.229 update.
Regression boundary on this machine (derived from
main.logby classifying every cross-sessionsend_messageagainst whether a matching record actually landed in the target session's transcript):[updater] Version changed since last launch: 1.26832.0 → 1.28929.0, CLI 2.1.222 → 2.1.227). One isolated earlier drop (and one a few days prior) suggests the failure mode existed rarely before this build and became deterministic with it.The blast radius is larger than "message not submitted." A dropped delivery wedges the receiving session, not just the sender:
isRunningand never clears it, since the CLI never echoes the injected input back.reason=no_response), and it has to be manually reopened.main.loglines that identify each stage:Confirmed on 10 separate occurrences across two long-lived sessions over 3 days — every
reason=no_responsestall in the logs begins at the exact second a cross-session message was injected, no exceptions. 68 consecutive cross-session deliveries dropped since the 08-12 00:58 boundary, including one confirmed live during this investigation (a session's own mandatory first-contact message appears inmain.logas sent but never reached the target's transcript).One thing that did not reproduce here: this issue's description says the dropped message is written to the target's transcript as a
last-promptrecord. Searching the target transcript forlast-promptentries containing the cross-session-message wrapper returns zero matches on this machine — worth noting as a platform/version difference, but the core symptom (silent drop, heldisRunning) is identical.Ruled out as contributing factors on this machine, with direct evidence: transcript file size, total session/file count, concurrent-session load, and memory pressure — happy to share the methodology if useful, didn't want to bloat this comment with it.
Confirming this bug — independent repro on a second Windows machine, with transcript-level measurements.
Setup: 7 long-running local sessions coordinating via
send_message(Windows 11 Home 10.0.26200, Claude Code desktop). The channel worked reliably for weeks (verified deliveries in transcripts through Aug 4-5), and was 100% dead when next exercised on Aug 14 — consistent with the Aug 12 regression window reported above.Measurements (Aug 14):
<cross-session-message ...>user turns for any of them in any receiver file.type: "user"turn whose content starts with the literal tag<cross-session-message from="local_..." name="..." encoded="1">. We have 176 transcript files containing such turns from the working period — none after the regression.Impact: multi-session orchestration (planner feeding worker sessions) is fully broken; a human has to hand-carry every message. Happy to provide sanitized transcript excerpts or run diagnostics if useful.
Confirming this regression on a newer build — 1.30096.1.0 (Windows 11 Pro 26200, MSIX) — with additional data points from an independent setup (two long-running local sessions + session-local hourly crons):
send_messagefrom another session reports success, the text lands visibly in the target session's composer, but is never auto-submitted; no assistant turn ever starts. Manually pressing Enter in that composer submits it instantly and the session responds normally — the delivery path works, only the auto-submit step is missing.send_message: session-local scheduled prompts (CronCreate fires) andScheduleWakeupwakeups targeting an idle session are lost the same way. If the target session is mid-turn, the queued message IS processed at the turn boundary — only cold deliveries to idle sessions fail.``
``22:27:37 [info] Resuming session local_d32822f1-… in C:\<workspace>\<project>
22:27:37 [info] Starting local session local_d32822f1-…
22:27:38 [info] Loaded 1165 transcript messages for session local_d32822f1-…
(no query/turn is ever logged)
22:33:50 [info] [WarmLifecycle:session] Starting idle timeout for local_d32822f1-…: 900s
The session warms, loads its transcript, then sits idle with the message in the composer.
claude_desktop_config.jsonmakes cold session starts die instantly (worker exits ~1s afterStarting local session,ProtocolErrorin main.log), which masks/compounds this issue with a different failure signature. Filing that separately.This effectively breaks all programmatic session orchestration on Windows (cross-session messaging, crons, self-scheduled wakeups). Happy to provide full logs or run a candidate build against our repro.
Update: still reproducible on 1.30096.5.0 (updated this morning, clean app start 08:46 local).
Same controlled repro as before — cross-session
send_messageto a small healthy idle session (1.1k transcript messages):So the delivery path works and the session warms, but the auto-submit step is still missing in 1.30096.5.0. MCP config in this environment is clean (the separate #86756 aggravator was eliminated before this test).
Confirming on a newer build, with a different variant and additional evidence
Environment
claude-desktopVariant: the message never reaches the composer
OP reports the message landing in the target's input composer. In my case it does not.
It renders as a
Message from <session>block inside the target's transcript, and thecomposer stays empty. The "type it by hand / press Enter" path does not apply — there is
nothing to submit. Pressing Enter does nothing.
New evidence: the model does not have the message in its context
The message is not merely unprocessed — it is absent from the model's context entirely.
ZX-4471-KOTWICAZX-4471-KOTWICApresent in your context? YES or NO."The token is random, so it cannot be matched by coincidence from files or prior history.
An earlier run with the plain 12-character string
hello there!produced the same result,so this is not a size or formatting issue.
Contrast: non-user injection works fine in the same session
Background-task notifications in that same session do reach the model's context as their
own turns — over a dozen of them, each with the
[SYSTEM NOTIFICATION - NOT USER INPUT]header and<task-notification>block. The modelenumerated them on request. So the general mechanism for injecting non-user content as a
turn is healthy; specifically the cross-session delivery path is not.
Ruled out
involved here:
ListAgentsnot in the tool registry,/list-agentsand/statusreturn"isn't available in this environment",
CLAUDE_CODE_MESSAGING_SOCKETandCLAUDE_CODE_MESSAGING_TOKENboth unset. This is purely theccd_session_mgmtpath.crossSessionInboundanywhere.~/.claude/settings.jsonis{}; project.claude/settings.jsondoes not exist;.claude/settings.local.jsoncontains onlypermissions.send_messagereports success every time. No error surfaces anywhere.Suggested addition to the repro: after delivery, ask the target session whether a
random token from the message is in its context. That separates "delivered but not
enqueued" from "not delivered at all" — and here it is the latter.
Data point supporting @ICEB-BB's variant — the variant changed between builds on the same machine:
Message from <session>block in the transcript, the composer stays empty, and there is nothing to submit — matching ICEB-BB exactly. A session visibly "showing" such a block produced no turn in 8+ minutes.So .1 → .5 moved the failure from "delivered to composer, auto-submit missing" to "rendered as transcript block, never enqueued to the model". The manual-Enter workaround that worked on .1 is gone on .5.
I know u guys are just posting the msgs from your agents, but at least ask them to not assume that a manual workaround that wasnt verified by more than one person ever existed... I have tried every manual workaround possible for a whole day before this thread was created since I thought it was caused by my plugin which was reading and creating tags based on the "
Message from <session>" and other parameters that gets sent... NOTHING WORKED FOR ME/ MY AGENTS. user messages, and even the whole message UI in a session were removed after the app was restarted, which means those weren't even saved by the harness and were blocked on that step.I am pretty sure whatever they changed between the .1 and .5 versions wasnt related to this bug and they probably didn't even notice it.
*tip: trying to find ways to fix this feels impossible, so dont waste tokens on workarounds. I wasted 2 research mode on GEMINI and like 6M claude tokens on this thing BEFORE this thread existed thinking it was my fault, and had to revert a lot of things i disabled because of this bug
Reproduction confirming this on 2.1.227 (desktop app, Windows 11 Pro 10.0.26200) — notable because it post-dates the 2.1.225 changelog fix for "cross-session messages staying parked without a notice or expiry," so the idle-recipient loss persists after that fix.
Setup: two ordinary sessions (one fresh/short, one long-running), messages sent via the session-management
send_messagetool while the recipient was idle.Result, confirmed in both directions:
send_messagereturns success; the message renders in the recipient's chat window (visible to the human).Contrast — the mid-turn path works: a message sent to a session that was actively mid-turn did reach its model (injected alongside a tool result, acknowledged late). The loss appears specific to the queued/idle path. A third observation: a message queued to a busy session whose in-flight turn was then interrupted by the user also never reached the model, consistent with this issue's note about queued messages being overwritten.
Real-world impact from the same evening: a coordination message warning another session about an impending merge conflict was never seen by its model, which then committed against exactly the warned-about state — only independent git verification prevented a bad merge.
Evidence caveats: one direction's non-delivery was verified via the recipient inspecting its own context directly (strong); the other via transcript rendering (weaker). Both recipients idle at send time; this reproduction covers the idle-recipient path only.
Confirming this on a second machine, same install type and same build, with a working baseline four days before the failure.
The build timeline is the part I think matters. Times are AWST, UTC+8.
| When | Claude Desktop build | Cross-session messaging |
|---|---|---|
| 8 Aug | 1.26832.0 | working, verified in recipient transcripts |
| 10 to 12 Aug 12:12 | 1.26832.0 | |
| 12 Aug 12:19 | 1.28929.0 | |
| 12 Aug 16:06 onward | 1.28929.0 | first confirmed failures |
| 14 Aug | 1.30096.1 | still failing |
| 15 Aug | 1.30096.5 | still failing |
The app was still running 1.26832.0 at 12:12 on 12 August and had restarted onto 1.28929.0 by 12:19. My first failed send was four hours later the same day. The build reported above shipped at 21:10 ET on 11 August, so this machine restarted onto it about three hours later. The fault has since survived two further updates.
Environment
Claude_1.30096.5.0_x64inC:\Program Files\WindowsApps\. The app's own updater log confirms it:[updater] MSIX detected: windowsStore=true, appPathMatch=true, source=windowsStoreSymptoms are identical to the report above. The tool returns a success string quoting the target's correct title, the message renders in full in the target's feed, the target flips to running, and the turn never completes. Nothing reaches the model.
Working to broken boundary, verified from transcripts
Method: take the exact message body out of the send call, grep every session transcript, and check which file it lands in.
Queue-level detail, which corroborates the last-prompt finding above
Typing one word into an idle session recorded the whole sequence in 91 milliseconds:
A cross-session message to that same session sixty seconds later produced no enqueue, no dequeue and no turn. The transcript gained only
last-promptandmoderecords, exactly as described above.Ruled out by test
Application log signature
For a send to an already-running target the app writes
Sending message to session, the same line it writes for typed input, but never writes aCycleHealthline for that session afterwards. For a send that has to start a stopped target it writesResuming session,Starting local sessionandLoaded N transcript messages, then nothing further.Effect on the target
The turn runs for minutes with no token counter, then ends without writing to the transcript and without logging an error.
lastActivityAtis left pinned to the moment of the send. The session is occupied for the duration but does recover on its own. The sending session is unaffected throughout.Happy to supply log excerpts and timestamps if useful.
Same symptom reproduces on macOS, on a much newer desktop build — so this does not look MSIX-specific.
I also ran a controlled comparison that isolates the fault to the desktop app's message-injection path, which may help narrow it down.
Environment
Symptom — identical to the original report
A cross-session message sent from the desktop app appears in the target session's UI as a card, but the receiving model is never invoked. No response, no thinking indicator.
In the target session's CLI transcript JSONL, the message is not written as a
type: "user"turn. The last records in the file are:The message content never appears in that file at all — the file's mtime was 6 minutes older than the send. Meanwhile the desktop app's own session store does have the message, which is why the card renders. So the message is retained on the app side and never handed to the CLI session.
The app's own health monitor flags it, roughly 1000 s later:
hadFirstResponse=falseis the signature: a cycle is started but no first response is ever produced. I have 10 such events across 6 different target sessions.Controlled comparison — same machine, same target session, same content
The only variable is the transport. The target session's CLI
sessionIdwas unchanged across both attempts.| | Desktop-app message tool | Native
SendMessage(2.1.224, per-session UDS in/tmp/cc-socks/) ||---|---|---|
| Record written to target's CLI transcript |
last-prompt(message body absent from file) |type: "user"turn, preceded by twoqueue-operationrecords || Model invoked | never | yes |
| Time to first assistant turn | n/a (still nothing after 28 min) | ~25 s |
| Repeat behaviour | 10/10 hung | 2/2 delivered |
The second row is the same message body that had failed minutes earlier over the first transport.
What this rules out for the failing path: the target CLI session (it was healthy and accepted the identical payload seconds later), the target being busy or cold, the socket layer, network, and permission settings. It points at the desktop app's injection step specifically — the step that should submit the stored prompt as a conversation turn.
Regression window here differs from the original report
no_responsein the app log: 2026-08-15 15:13 (+08:00)no_responseevents before that pointSo it broke inside a ~7.5 h window on 2026-08-15, whereas the original report bisects to 2026-08-12 on Windows. Three days apart, on different platforms and different app versions — consistent with a staged rollout of the same change, but I can't confirm they share a root cause from my side.
Also matches
The "queued messages overwrite each other" behaviour described in the original report is consistent with what I saw: when several messages were sent in sequence, only some left any trace.
Question
Given the platform and version difference, is this the same issue, or would you prefer a separate macOS report? Happy to provide the log excerpts or transcript record types in whatever form is useful.
A quick note for anyone hitting this:
hadFirstResponse=false, reason=no_responsein the app log is a reliable fingerprint, and the nativeSendMessagetool is an alternative path that worked here.Additional data point — second machine, same symptom, consistent
failure over two days.
Environment: Windows 11 Pro 26200, MSIX install, ~11 concurrent
sessions in a single repo.
What we observed (2026-08-15 and 08-16):
· Cross-session messages return "Message sent" and the target
never produces a turn. Three managers in a row independently
concluded the channel was broken.
· One of them built a workaround that reads messages directly
from the sender's transcript files on disk, bypassing the
queue entirely. It surfaced 2 messages that had been sitting
undelivered — confirming the messages exist on disk and only
the submit step fails. This matches your finding that they are
stored as a pending last-prompt rather than a user turn.
· Background agents were completely unaffected — 12/12 delivered
and returned. Only session-to-session is broken.
Scope, as far as we can measure it: across two full days and
roughly a dozen attempts, we have not observed a single
successful automatic delivery. Every message that reached its
target did so because the user copied it manually. We briefly
believed one had gone through on its own; on checking, the user
confirmed he had pasted it. So we have no counter-example.
On impact, since it may help prioritize: the lost messages were
not the expensive part. Three separate managers built reasoning
on the absence of replies. One recorded "the channel is broken
in both directions" as an established fact and passed it forward
as a lesson to the next session. That conclusion was wrong, and
it nearly became institutional knowledge. The silent-overwrite
behaviour you documented compounds this — there is no signal
distinguishing "not delivered" from "nobody answered yet".
One suggestion, independent of fixing the submit path: making
"sent" and "delivered" distinct in the return value would have
prevented every wrong conclusion above. A sender that can tell
the difference stops guessing.
Refinement on the visible symptom, in case it helps narrow the
mechanism.
On our machine the message does not stay in the composer. It
renders in the target session's conversation as a normal
"Message from <sender>" block, and the composer stays empty.
But the target never produces a turn — it continues whatever it
was doing, as if nothing arrived.
So the visible symptom differs from your report, while the
underlying behaviour appears identical and matches your JSONL
finding: the message is recorded as a pending prompt rather than
a user turn. The UI renders it; nothing ever invokes the model.
We think that distinction is worth separating in the title or
repro steps, because "delivered" and "displayed" look the same
to an observer. Someone watching the target's screen sees the
message and concludes delivery succeeded. It did not.
Timeline matches yours: our failures also began around
2026-08-12. Before that, inter-session messaging worked normally
in this repo for weeks. Happy to test a fix build.
Adding an independent data point that matches this report closely — same platform (Windows 11, desktop app), similar timeframe (noticed 2026-08-15/16, could have started earlier and just gone unnoticed).
Setup: multiple long-running Claude Code sessions in the desktop app, coordinating on a shared project via
send_message(theccd_session_mgmtMCP tool). Sessions have been messaging each other reliably for weeks; the failure appeared abruptly.Symptoms observed, matching this issue and #86014/#78338:
send_messageconsistently returns success (Message sent to session <id> ("<title>")), but the target session frequently never acts on it.isRunning: true(mid-turn) at the moment of sending, delivery reliably failed to surface. When the target was idle, the message was picked up on the target's next turn, but only once something caused that session to run again (matches #66310's "queue only flushes on next send" behavior) — a genuinely idle session did not spontaneously wake up to process it.This is consistent with #78338's root-cause writeup (destructive dequeue before delivery is confirmed) — from the outside it presents exactly as: success is returned, but a message sent while the target is mid-turn has a good chance of silently vanishing, and even for idle targets nothing proactively drains the queue.
Happy to provide more detail (session/build info) if useful — just didn't want to post raw internal session IDs/business context here.
Confirmed on a newer MSIX build — 1.30096.5.0 (Windows 10 Pro 19045, Claude Code CLI 2.1.220).
Same shape as OP with one additional data point: after
send_messagereturned success to the sender, the message card rendered normally in the target session's transcript UI — but when we asked the target session directly, the model stated nothing inbound had reached its context that entire session. So this isn't just "composer never submits"; the sender gets success, the human sees a delivered-looking card, and the model provably never receives it. Every layer reports fine except the one that matters.Target was an idle (not running) session attached to a git worktree, sender was a plain session in the same repo, both local.
crossSessionInbound: "accept"is set globally. Delivery worked reliably for us before ~Aug 11, consistent with OP's timeline.Workaround we've adopted: treat any send without an explicit model-acknowledgment as undelivered, and fall back to files on disk for anything operational.
<html>
<body>
<!--StartFragment--><p style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px 0px 16px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); text-rendering: optimizelegibility; color: rgb(240, 239, 236); font-family: anthropic-sans, system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(21, 21, 21); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">Confirming this on<span> </span><strong style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-weight: 500; font-variation-settings: "opsz" 16, "wght" 560; text-rendering: optimizelegibility;">Windows 11, Claude Code 2.1.229</strong><span> </span>— same failure mode.</p><p style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px 0px 16px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); text-rendering: optimizelegibility; color: rgb(240, 239, 236); font-family: anthropic-sans, system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(21, 21, 21); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><strong style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-weight: 500; font-variation-settings: "opsz" 16, "wght" 560; text-rendering: optimizelegibility;">Reproduction (two live tests today):</strong></p><ol style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px 0px 16px; padding: 0px 0px 0px 20px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); list-style: decimal; text-rendering: optimizelegibility; gap: 6px; flex-direction: column; display: flex; color: rgb(240, 239, 236); font-family: anthropic-sans, system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(21, 21, 21); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><li style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); text-rendering: optimizelegibility;"><p style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); text-rendering: optimizelegibility;">Target session<span> </span><strong style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-weight: 500; font-variation-settings: "opsz" 16, "wght" 560; text-rendering: optimizelegibility;">idle but alive</strong><span> </span>(<code node="[object Object]" data-epitaxy-inline-code="" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-family: anthropic-mono, ui-monospace, monospace; font-feature-settings: "calt" 0, "liga" 0; font-variation-settings: normal; font-size: 12px; font-variant-ligatures: none; text-rendering: optimizelegibility; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(255, 255, 255, 0.08); color: rgb(225, 224, 217); border-radius: 4px; padding-block: 1px; padding-inline: 2px; line-height: 1.4;">isRunning: true</code>, waiting for input):<span> </span><code node="[object Object]" data-epitaxy-inline-code="" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-family: anthropic-mono, ui-monospace, monospace; font-feature-settings: "calt" 0, "liga" 0; font-variation-settings: normal; font-size: 12px; font-variant-ligatures: none; text-rendering: optimizelegibility; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(255, 255, 255, 0.08); color: rgb(225, 224, 217); border-radius: 4px; padding-block: 1px; padding-inline: 2px; line-height: 1.4;">send_message</code><span> </span>returned<span> </span><code node="[object Object]" data-epitaxy-inline-code="" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-family: anthropic-mono, ui-monospace, monospace; font-feature-settings: "calt" 0, "liga" 0; font-variation-settings: normal; font-size: 12px; font-variant-ligatures: none; text-rendering: optimizelegibility; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(255, 255, 255, 0.08); color: rgb(225, 224, 217); border-radius: 4px; padding-block: 1px; padding-inline: 2px; line-height: 1.4;">Message sent to session X</code>. The message<span> </span><strong style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-weight: 500; font-variation-settings: "opsz" 16, "wght" 560; text-rendering: optimizelegibility;">never appeared in the target's transcript at all</strong><span> </span>— not as a<span> </span><code node="[object Object]" data-epitaxy-inline-code="" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-family: anthropic-mono, ui-monospace, monospace; font-feature-settings: "calt" 0, "liga" 0; font-variation-settings: normal; font-size: 12px; font-variant-ligatures: none; text-rendering: optimizelegibility; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(255, 255, 255, 0.08); color: rgb(225, 224, 217); border-radius: 4px; padding-block: 1px; padding-inline: 2px; line-height: 1.4;">user</code><span> </span>turn, not as a queued item, not even as a<span> </span><code node="[object Object]" data-epitaxy-inline-code="" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-family: anthropic-mono, ui-monospace, monospace; font-feature-settings: "calt" 0, "liga" 0; font-variation-settings: normal; font-size: 12px; font-variant-ligatures: none; text-rendering: optimizelegibility; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(255, 255, 255, 0.08); color: rgb(225, 224, 217); border-radius: 4px; padding-block: 1px; padding-inline: 2px; line-height: 1.4;">lastPrompt</code><span> </span>record. The target's<span> </span><code node="[object Object]" data-epitaxy-inline-code="" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-family: anthropic-mono, ui-monospace, monospace; font-feature-settings: "calt" 0, "liga" 0; font-variation-settings: normal; font-size: 12px; font-variant-ligatures: none; text-rendering: optimizelegibility; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(255, 255, 255, 0.08); color: rgb(225, 224, 217); border-radius: 4px; padding-block: 1px; padding-inline: 2px; line-height: 1.4;">.jsonl</code><span> </span>was actively being written at the time, so this isn't a flush lag.</p></li><li style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); text-rendering: optimizelegibility;"><p style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); text-rendering: optimizelegibility;">Target session<span> </span><strong style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-weight: 500; font-variation-settings: "opsz" 16, "wght" 560; text-rendering: optimizelegibility;">busy (mid-turn)</strong>:<span> </span><code node="[object Object]" data-epitaxy-inline-code="" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-family: anthropic-mono, ui-monospace, monospace; font-feature-settings: "calt" 0, "liga" 0; font-variation-settings: normal; font-size: 12px; font-variant-ligatures: none; text-rendering: optimizelegibility; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(255, 255, 255, 0.08); color: rgb(225, 224, 217); border-radius: 4px; padding-block: 1px; padding-inline: 2px; line-height: 1.4;">send_message</code><span> </span>returned a<span> </span><em style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); text-rendering: optimizelegibility; font-style: italic;">different</em><span> </span>string —<span> </span><code node="[object Object]" data-epitaxy-inline-code="" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-family: anthropic-mono, ui-monospace, monospace; font-feature-settings: "calt" 0, "liga" 0; font-variation-settings: normal; font-size: 12px; font-variant-ligatures: none; text-rendering: optimizelegibility; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(255, 255, 255, 0.08); color: rgb(225, 224, 217); border-radius: 4px; padding-block: 1px; padding-inline: 2px; line-height: 1.4;">Message queued for session X; it will be processed after the in-flight turn finishes if that session stays healthy</code>. The UI rendered the "message from …" card and showed a running spinner, but<span> </span><strong style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-weight: 500; font-variation-settings: "opsz" 16, "wght" 560; text-rendering: optimizelegibility;">no assistant turn was ever produced</strong><span> </span>and nothing landed in the transcript. (This matches the behaviour in<span> </span><a href="https://github.com/anthropics/claude-code/issues/61718" target="_blank" rel="noreferrer" class="text-accent hover:underline underline-offset-[1px] outline-none hide-focus-ring ring-focus rounded-r2" id="base-ui-_r_1ts5_" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline: none; scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); app-region: no-drag; color: rgb(109, 167, 236); text-decoration: none; outline-offset: 2px; text-underline-offset: 1px; --tw-outline-style: none; border-radius: 3px; text-rendering: optimizelegibility; cursor: pointer;">#61718</a>.)</p></li></ol><p style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px 0px 16px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); text-rendering: optimizelegibility; color: rgb(240, 239, 236); font-family: anthropic-sans, system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(21, 21, 21); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">So the sender-side result string branches on target state, but<span> </span><strong style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-weight: 500; font-variation-settings: "opsz" 16, "wght" 560; text-rendering: optimizelegibility;">neither path delivers</strong>. The unconditional success-like return is the core hazard: the sender plans around "delivered", the receiver never sees it, and nobody is told to retry.</p><p style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px 0px 16px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); text-rendering: optimizelegibility; color: rgb(240, 239, 236); font-family: anthropic-sans, system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(21, 21, 21); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><strong style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-weight: 500; font-variation-settings: "opsz" 16, "wght" 560; text-rendering: optimizelegibility;">Transcript-level evidence (receiver<span> </span><code node="[object Object]" data-epitaxy-inline-code="" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-family: anthropic-mono, ui-monospace, monospace; font-feature-settings: "calt" 0, "liga" 0; font-variation-settings: normal; font-size: 12px; font-variant-ligatures: none; text-rendering: optimizelegibility; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(255, 255, 255, 0.08); color: rgb(225, 224, 217); border-radius: 4px; padding-block: 1px; padding-inline: 2px; line-height: 1.4;">.jsonl</code>):</strong><span> </span>In the working period, incoming messages appeared as<span> </span><code node="[object Object]" data-epitaxy-inline-code="" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-family: anthropic-mono, ui-monospace, monospace; font-feature-settings: "calt" 0, "liga" 0; font-variation-settings: normal; font-size: 12px; font-variant-ligatures: none; text-rendering: optimizelegibility; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(255, 255, 255, 0.08); color: rgb(225, 224, 217); border-radius: 4px; padding-block: 1px; padding-inline: 2px; line-height: 1.4;">queue-operation</code>/<code node="[object Object]" data-epitaxy-inline-code="" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-family: anthropic-mono, ui-monospace, monospace; font-feature-settings: "calt" 0, "liga" 0; font-variation-settings: normal; font-size: 12px; font-variant-ligatures: none; text-rendering: optimizelegibility; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(255, 255, 255, 0.08); color: rgb(225, 224, 217); border-radius: 4px; padding-block: 1px; padding-inline: 2px; line-height: 1.4;">enqueue</code><span> </span>records containing a<span> </span><code node="[object Object]" data-epitaxy-inline-code="" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-family: anthropic-mono, ui-monospace, monospace; font-feature-settings: "calt" 0, "liga" 0; font-variation-settings: normal; font-size: 12px; font-variant-ligatures: none; text-rendering: optimizelegibility; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(255, 255, 255, 0.08); color: rgb(225, 224, 217); border-radius: 4px; padding-block: 1px; padding-inline: 2px; line-height: 1.4;"><cross-session-message from="…"></code><span> </span>payload, immediately followed by<span> </span><code node="[object Object]" data-epitaxy-inline-code="" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-family: anthropic-mono, ui-monospace, monospace; font-feature-settings: "calt" 0, "liga" 0; font-variation-settings: normal; font-size: 12px; font-variant-ligatures: none; text-rendering: optimizelegibility; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(255, 255, 255, 0.08); color: rgb(225, 224, 217); border-radius: 4px; padding-block: 1px; padding-inline: 2px; line-height: 1.4;">dequeue</code><span> </span>and a normal assistant turn. Since the regression, those enqueue records stop appearing entirely; the only new prompts in the queue are ones the user typed by hand.</p><p style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px 0px 16px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); text-rendering: optimizelegibility; color: rgb(240, 239, 236); font-family: anthropic-sans, system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(21, 21, 21); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><strong style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-weight: 500; font-variation-settings: "opsz" 16, "wght" 560; text-rendering: optimizelegibility;">Version bisection (may help narrow the offending release):</strong></p><div class="overflow-x-auto" style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px 0px 16px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); overflow-x: auto; text-rendering: optimizelegibility; color: rgb(240, 239, 236); font-family: anthropic-sans, system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(21, 21, 21); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
Date | Claude Code | Cross-session delivery
-- | -- | --
2026-08-07 | 2.1.222 | last successful automatic delivery
2026-08-12 | 2.1.227 | broken
2026-08-17 | 2.1.229 | still broken
</div><p style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px 0px 16px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); text-rendering: optimizelegibility; color: rgb(240, 239, 236); font-family: anthropic-sans, system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(21, 21, 21); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">So the break landed somewhere in<span> </span><strong style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); font-weight: 500; font-variation-settings: "opsz" 16, "wght" 560; text-rendering: optimizelegibility;">2.1.223–2.1.227</strong>. This is consistent with the "worked until ~2026-08-11, 100% failure since" timing reported here.</p><p style="box-sizing: border-box; border: 0px solid color(srgb 1 1 1 / 0.1); margin: 0px 0px 16px; padding: 0px; outline-color: rgb(85, 152, 231); scrollbar-width: thin; scrollbar-color: rgba(225, 224, 217, 0.35) rgba(0, 0, 0, 0); text-rendering: optimizelegibility; color: rgb(240, 239, 236); font-family: anthropic-sans, system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-size: 13px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(21, 21, 21); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">Workaround in use: the "message from …" card still renders, so it serves as a notification to manually switch to the target session and re-enter the prompt there by hand.</p><!--EndFragment-->
</body>
</html>Confirming this on Windows 11, Claude Code 2.1.229 — same failure mode.
Reproduction (two live tests today):
Target session idle but alive (isRunning: true, waiting for input): send_message returned Message sent to session X. The message never appeared in the target's transcript at all — not as a user turn, not as a queued item, not even as a lastPrompt record. The target's .jsonl was actively being written at the time, so this isn't a flush lag.
Target session busy (mid-turn): send_message returned a different string — Message queued for session X; it will be processed after the in-flight turn finishes if that session stays healthy. The UI rendered the "message from …" card and showed a running spinner, but no assistant turn was ever produced and nothing landed in the transcript. (This matches the behaviour in #61718.)
So the sender-side result string branches on target state, but neither path delivers. The unconditional success-like return is the core hazard: the sender plans around "delivered", the receiver never sees it, and nobody is told to retry.
Transcript-level evidence (receiver .jsonl): In the working period, incoming messages appeared as queue-operation/enqueue records containing a <cross-session-message from="…"> payload, immediately followed by dequeue and a normal assistant turn. Since the regression, those enqueue records stop appearing entirely; the only new prompts in the queue are ones the user typed by hand.
Version bisection (may help narrow the offending release):
Date Claude Code Cross-session delivery
2026-08-07 2.1.222 last successful automatic delivery
2026-08-12 2.1.227 broken
2026-08-17 2.1.229 still broken
So the break landed somewhere in 2.1.223–2.1.227. This is consistent with the "worked until ~2026-08-11, 100% failure since" timing reported here.
Workaround in use: the "message from …" card still renders, so it serves as a notification to manually switch to the target session and re-enter the prompt there by hand.
NOT FIXED YET IN THE NEW UPDATE. i restarted the app, created new sessions, same issues. my tip: temporarily become the messenger for ur agents and ask for copypastables instead.
IF ANYONE created a better mechanism like an inbox or something, tell me, it is the next thing im going to make my plugin do but it will be so stupid if they fix this by next week...
<img width="1778" height="1584" alt="Image" src="https://github.com/user-attachments/assets/b8326098-271e-4e17-8dba-3ad8a4bd283f" />
it got the message MID TURN, next it ignores my message and is still wedged. hope i saved u guys some tokens out of testing.
<img width="1718" height="1570" alt="Image" src="https://github.com/user-attachments/assets/c33c4ff2-2594-4d2f-b182-85ab65aad15d" />
Solved on our machine — it took two changes, not one
Windows 11 / Claude Desktop (MSIX). We hit exactly this: the message lands in the recipient's transcript,
isRunningflips totrue, and then… nothing. No model turn, ever.Both of these were required. Either one alone still fails — we measured each combination:
| runtime |
crossSessionInbound| result ||---|---|---|
| 2.1.229 |
"accept"| ❌ silently dropped — 2.1.229 misreads the setting (this is the bug) || 2.1.234 | (unset → default) | ❌ still dropped — it now reads the setting correctly and honors it |
| 2.1.234 |
"accept"| ✅ works, both directions |1. The runtime the Desktop app actually uses is pinned and does not auto-update
Updating Claude Desktop was not enough. The app kept launching:
…even after a Desktop update bumped the shell version. A separate newer CLI on
PATHis irrelevant — the Desktop never uses it. We replaced the pinned binary in place with 2.1.234 (keeping a backup) and verified withclaude.exe --versionthat the file inside the2.1.229folder actually reports2.1.234. Checking the folder name proves nothing.2. The setting did not exist at all, so it ran on a default that isn't
acceptThere was no
crossSessionInboundkey anywhere in our config — no user settings, no managed settings. Adding it explicitly to~/.claude/settings.jsonis what finally closed it:This is the part that surprised us. The 2.1.234 fix is described as messages being dropped "when cross-session messaging read as disabled" — so once the read is fixed, an unset/non-accept default is faithfully obeyed and messages keep getting held. The fix works; it just reveals the setting.
⚠️ A measurement trap that cost us two invalid tests
If the recipient session has a stuck/in-flight turn, the tool returns:
That is not delivery, and the test measures nothing.
isRunning: trueis likewise not evidence — it flips just from the message arriving. The only proof is new assistant output in the recipient. We caught this because the UI spinner had been counting for 13 minutes; pressing Stop on the recipient first made the next test valid.Verification we'd suggest for anyone re-testing
Use a unique marker string, confirm the recipient is genuinely idle, and check the recipient's own transcript for new assistant output containing that marker — not the sender's success message. Ours came back both ways:
Two Claude Code sessions now hand work back and forth unattended, which is the whole point.
---
Small note to the Anthropic folks: we lost a full night of debugging to this one, and our coordinator session confidently announced "FIXED" once before actually measuring — so it learned "a match is not a proof" the hard way too. We'll take the fix as the gift. Although if presents are being handed out, a runtime version that isn't pinned three patches behind the shell would make a lovely one. 🎁
@panteliskopsias i would have given up if not for u
BOTH DIRECTIONS NOW WORK — and our case needed only ONE of your two changes
Windows 11, Claude Desktop MSIX, same symptom: message lands, isRunning flips, no turn.
Your table was the whole fix. Five things we hit that it does not cover:
MSIX virtualizes it. A shell running INSIDE the container resolves
%APPDATA%\Claude\claude-code\2.1.229\claude.exe correctly; Explorer, outside it, returns
"Windows can't find". The real path is
C:\Users\<you>\AppData\Local\Packages\Claude_<hash>\LocalCache\Roaming\Claude\claude-code\<ver>\
Your instructions are correct in-container and unusable from Explorer. Worth stating which.
claude updatefetches it.It lands in ~/.local/bin/claude.exe and ~/.local/share/claude/versions/. Copy from there.
cpover the live binary fails with"Device or resource busy", but Windows lets you RENAME a running .exe. Rename it aside to free
the name, then copy 2.1.234 in:
claude.exe -> claude_2.1.229.exe (name backups by VERSION, not _COPY)
claude_2.1.231.exe (keep any interim ones, same scheme)
cp <new> claude.exe
The folder name stays 2.1.229 and that is fine, as you said.
After swapping, logs/main.log still printed
[CCD] Initialized with version 2.1.229
because that line reads the FOLDER NAME, not the binary. We nearly concluded the swap failed.
What actually reports the running build is the "version" field on every row of the session
transcript, ~/.claude/projects/<slug>/<id>.jsonl. Ours flipped 2.1.229 -> 2.1.234 there while
main.log never moved.
(1.32352.1.0), same pinned 2.1.229. The pin is per-Desktop-release, so a reinstall of the
release you already have re-pins what you already had. Related: #84823.
OUR ROW OF YOUR TABLE: crossSessionInbound was ALREADY "accept" here, so only the runtime was
wrong — 2.1.229 + accept, your row 1. One change, not two. Worth noting the setting can be
correct while the bug still bites, which makes "check the setting first" a fast triage step.
PROOF, both directions, measured rather than asserted — and this matters because today's failure
mode was a message that RENDERS without entering context, so "the recipient says it arrived" is
unfalsifiable from outside. We grepped each other's transcripts:
BOSS7 -> Plugin-2 marker in Plugin-2's .jsonl as type:"user", 09:48:55, version=2.1.234
control 'cross-session-message' = 93
Plugin-2 -> BOSS7 its reply row present in ours
The receiving session reported its first inbound delivery since 2026-08-11.
Thanks for the write-up — we would still be hand-relaying without it.
Update from an affected Windows/MSIX user (Aug 19):
The changelog for 2.1.235 mentions cross-session messaging fixes, but Windows desktop users may be unable to receive them because the desktop engine updater appears stalled:
Questions: is the desktop engine rollout on Windows staged or stalled? Will the messaging fix ship in an upcoming MSIX build?
Environment: Windows 11 Pro 10.0.26200 · MSIX app 1.32352.1.0 · engine 2.1.229.
Same symptom here on Windows Desktop (MSIX), and a concrete way to confirm @sc0x01's point about the engine updater — plus a workaround that doesn't depend on it.
Checking your engine version separately from the app version. The About dialog shows the app version (mine reads
1.32885.1), which is not the Claude Code engine the session actually runs. The engine version is in%USERPROFILE%\.claude.json:Mine sits at 2.1.233 while Desktop reports nothing to update — one version below the 2.1.234 that several people here report as fixed. That matches @sc0x01's observation, and it means "I'm on the latest app" and "I have the fix" are different claims. Worth checking that key before concluding your build is current.
A workaround that doesn't need the engine fix at all. Rather than wait, I moved delivery into a
Stophook, which works on 2.1.233 today:Stophook returns{"decision":"block","reason":"..."}on stdout, which injects the text and continues the turn. One thing that cost me an hour: onStop, stderr is not fed back to Claude — exit-2-with-stderr keeps the session alive while delivering nothing.async: true, asyncRewake: trueruns in the background and exiting 2 wakes an idle session, delivering its stderr as a system reminder.That second mechanism is the part I hadn't seen mentioned in these threads. It also covers something the 2.1.234 fix doesn't appear to: reading the reports here closely, they describe delivery into an in-progress or about-to-start turn, not a session sitting fully idle with no pending work. In my testing a session idle for ~13 hours was woken in about a second.
Implementation, PowerShell only — no Node, Bun, CLI or WSL: https://github.com/msiraga/claude-code-windows-mailbox
It includes a self-test (
verify.ps1, 26 checks against a throwaway mailbox) because every result I have is from one machine. I don't have a second Windows box to confirm on, so the self-test exists to make that cheap for anyone who does — if you run it, I'd genuinely like to know what it says.One caveat worth stating: I also measured
/list-agentsreturningUnknown commandon 2.1.237 in a Windows CLI session, which per the availability docs suggests the feature isn't offered on Windows at all rather than being broken. If that reading is wrong, the measurement still stands and the workaround still works — only the explanation changes.Reproduced on Windows 11 Pro 10.0.26200, Claude Desktop MSIX/Store 1.32885.1.0, on 20 August 2026. The machine has since auto-updated to 1.34493.1.0 and I have not retested on that build; I will report if the behaviour changes.
The recipient was mid-turn, so this exercises the deferred path. One comment above reads the fault as idle-recipient delivery being specifically broken. That is not the whole of it. The send was queued behind an in-flight turn, drained when that turn completed, and was still lost.
The cross-session send was issued at 09:38:33 local and the recipient was busy, so it was deferred. The recipient's in-flight turn ended at 09:40:53, and everything below happens in that same second. Session id redacted:
The turn ends, the app drains the deferred send into the input stream, and in the same second the session is held by unechoed input.
hasPendingCycle: truewithinputStreamHasPending: falseis the loss stated in the app's own fields: a cycle is pending and there is nothing in the input stream to feed it. It never becomes a turn. I have not seendrained N deferred send(s)quoted elsewhere in this thread.Verification that nothing arrived. The recipient's transcript holds 150 records between 01:37:00Z and 02:16:08Z, and no inbound user turn carrying the message body at any point. The send was at 01:38:33Z. The only inbound turn referencing the message is a header I pasted by hand at 02:12:05Z to recover it from a file, 33 minutes and 32 seconds later. The sender's result string reported success throughout.
What this looks like from the user's side. Part way through I typed to the recipient session, "but i can see it in your feed". It could not see it in its context. The message was rendered on my screen and absent from the model's input at the same moment, and there is nothing in the interface that distinguishes the two.
One thing that is not a signal, in case anyone is reading build-to-build differences off it. The tool returns either "Message sent to session ..." or "Message queued for session ...; it will be processed after the in-flight turn finishes". Both strings have coexisted since at least 17 July, and I counted 115 "queued" results on 8 August, a day when delivery verifiably worked. Which one you get depends on whether the target has a turn in flight. It says nothing about whether the message will arrive.
I can supply a filtered excerpt of the LocalSessionManager, CycleHealth and Stop hook lines for that window if useful.
Resolved here without touching a binary — and our row of @panteliskopsias's table disagrees with theirs. Windows 11 Pro 10.0.26200, Claude Desktop MSIX. We are the original reporter.
The engine updater is not stalled everywhere — it moved here on its own
Answering @sc0x01's question with our data point. On 2026-08-21 the engine directory went from holding
2.1.227+2.1.229to holding only2.1.237(folder mtime 17:35 local). We swapped nothing, renamed nothing, and did not reinstall. So the rollout does reach at least some MSIX machines unprompted.The flip is visible mid-session, which is worth knowing if you are dating your own repro:
Two triage notes for anyone reading versions off the wrong place:
%USERPROFILE%\.claude.jsonhas nolastVersionBasekey at all on this machine, so @msiraga's triage step is not universal. Theversionfield on transcript rows — @TomerBrosh's method — is the one that worked for us.2.1.229. That is exactly row 1 of the table. Same machine, same install, only the engine changed.crossSessionInboundwas not required — this contradicts row 2@panteliskopsias's table says
2.1.234+ unset → "still dropped — it now reads the setting correctly and honors it". That is not what we see on 2.1.237. The key is absent from every settings location we can find:| location | state |
|---|---|
|
~/.claude/settings.json| key absent || project
.claude/settings.json| file does not exist || project
.claude/settings.local.json| key absent ||
C:\ProgramData\ClaudeCode\managed-settings.json| directory does not exist |And the channel works both directions anyway. So either the default changed between
2.1.234and2.1.237, or something other than that key was in play on their machine. Worth knowing before anyone adds the setting believing it is mandatory — for us the runtime was the only variable.Idle-recipient wake works natively on 2.1.237, no Stop hook needed
Measured per the verification protocol in this thread — unique marker, genuinely idle recipient, and we read the recipient's transcript rather than the sender's result string. Recipient's previous turn ended
2026-08-22T20:09:29Z, so it had been idle ~13 h.No human action at either end. This is the fully-idle case @msiraga described as uncovered by the
2.1.234fix — on2.1.237it is covered, and the PowerShell mailbox is not needed for it. Thetype="user"row at 06:58:02 is worth calling out: that row alone is exactly what the failure looked like too. The only thing that separates working from broken is whether anassistantrow follows it, which is why the sender'ssuccess: trueis worthless as evidence.What we did not test
The deferred path @alexmaguire-dev reports today — recipient mid-turn, send drained on turn end, lost to
isRunning held by unechoed input. Our second session was mid-turn and we chose not to disturb it, so we can neither confirm nor refute that on2.1.237. Our result covers the idle path only, and we have written it into our own project rules that way rather than as "the channel works".One unrelated measurement
@msiraga read
/list-agentsreturningUnknown commandon2.1.237as the feature not being offered on Windows. In a Claude Desktop session on2.1.237here, the agent-listing tool works and correctly enumerated both peer sessions with their idle/busy state. So whatever the CLI is doing, it is not a platform-wide absence.Thanks to everyone who did the version archaeology in this thread — the "app version ≠ engine version" distinction is the whole diagnosis, and we would have gone on blaming the tool.
One thing that may matter for anyone trying to reproduce this: the failure is intermittent, not constant.
Measured today on desktop 1.34493.1.0, across at least ten cross-session sends between local sessions: four delivered, six lost. Roughly 40% delivery. Every send returned a success string.
The practical consequence: a single successful send is not evidence the bug is gone. A one-shot reproduction attempt has a good chance of passing by luck. Two people here concluded the fault had cleared on the strength of one message arriving, and were wrong both times. Any repro needs a run, not a probe.
Two distinct failure shapes, which may not be one bug:
Sending message to sessionand noMapping internal sessionfollows. Consistent with the held-then-expired path described in #86298.Resuming session,Starting local session,Loaded N transcript messages— and nothing else. Three of six losses were this shape.A caution if you are counting from the log: shape 2 is invisible to it, so any tally built that way undercounts losses. It classifies a known send; it cannot enumerate them.