[BUG] send_message reports success on native Windows where cross-session messaging is not offered — no inbox socket bound, nothing delivered, caller cannot tell (worked on this machine until 2026-08-11)
Supersedes and extends our earlier report our earlier internal report (2026-08-13). What is new here: the queue mechanism itself, measured on both sides of the regression, plus a correction to that earlier report's claim that the payload is stored encoded. It is stored in plaintext, which makes this cheaply greppable and changes how it should be triaged.
---
1 · Summary
send_message (cross-session) returns a success string naming the correct target. On the target:
- the session wakes —
isRunningflipsfalse → trueandlastActivityAtadvances to the send instant; - it runs for roughly 1–2 seconds;
- no
queue-operationrecord is written, the transcript does not grow, and no turn is produced; - the session is left
isRunning: trueand does not recover on its own.
The distinguishing measurement in this report: when this feature worked, delivery wrote aqueue-operation / operation:"enqueue" record carrying the message body in plaintext, immediately
followed by a dequeue. In the broken state that enqueue record is simply never written. The wake-up
still happens, so the notification path is intact and the enqueue/persist path is what fails.
---
2 · Environment
| | |
|---|---|
| OS | Windows 11 Home, 10.0.26200 (build reported by the shell as 10.0.26200.9168) |
| App | Claude, MSIX / Store install |
| Version tested (still broken) | 1.30096.1.0 — PackageFullName: Claude_1.30096.1.0_x64__pzs8sxrjxfjjc |
| Package write time | 2026-08-14 12:22:58 +0800 (this build was installed ~35 min before the probe below) |
| Version implicated in the regression | 1.28929.0 (per #86069; its changelog covers "failing to save chat history, settings, and scheduled tasks") |
| Sessions involved | Ordinary local interactive sessions, same project directory. Neither is a scheduled task, remote dispatch, or worktree session. |
| Target state at send | Idle and finished — last activity 3 days earlier |
⚠ This is still broken on 1.30096.1.0. The August cross-session fix we can find in the release
notes addresses *"messaging sometimes starting without an inbox in the first session after install or
upgrade"*, which is a different symptom.
---
3 · The mechanism, measured on both sides — this is the part we think is new
3.1 · WORKING (before the regression)
A delivered prompt is written to the target's transcript .jsonl as a queue operation with the body
in plaintext, then dequeued ~200 ms later:
{"type":"queue-operation","operation":"enqueue","timestamp":"2026-08-11T21:56:39.525Z",
"sessionId":"<session-B-uuid>",
"content":"<session B's first prompt text>"}
{"type":"queue-operation","operation":"dequeue","timestamp":"2026-08-11T21:56:39.747Z",
"sessionId":"<session-B-uuid>"}
And the same shape holds for a genuine cross-session delivery, including the From {sender title}
envelope the feature adds:
{"type":"queue-operation","operation":"enqueue","timestamp":"2026-07-25T14:56:30.351Z",
"sessionId":"<session-uuid>",
"content":"From <sender session title> \n\n\n<message body, stored verbatim and unencoded>"}
3.2 · BROKEN (now)
Same target session, same machine, probe at 2026-08-14T04:57:36Z:
send_message→Message sent to session local_<session-B-id> ("Session B")get_session→isRunning: true,lastActivityAt: "2026-08-14T04:57:36.230Z"(was2026-08-11T21:56Z)- target transcript: 10 lines before, 10 lines after
- records dated
2026-08-14in the target transcript:0 queue-operationrecords dated today:0— noenqueue, nodequeue- transcript file mtime advances to
12:57:37 +0800(= the send instant) while gaining no records .claude.jsonand its backup written at the same second — neither contains the payload
⇒ The session is woken and something rewrites state, but the prompt is never enqueued.
---
4 · Reproduction
- Session A and session B, both ordinary local interactive sessions. Leave B idle and finished.
- From A, call
send_messageat B with a unique marker string in the body. - Read the tool's return value. (It will claim success.)
get_session(B)→ observeisRunning: trueandlastActivityAtat the send instant.- Grep B's transcript
.jsonlforqueue-operation, and for the marker.
Expected: an enqueue record containing the marker, then a dequeue, then a turn.
Actual: neither record appears; the transcript does not grow; B stays isRunning: true indefinitely.
---
5 · Controls we ran, so the negatives are trustworthy
| control | result | what it rules out |
|---|---|---|
| Grep the marker across all transcripts | found only in the sender's own transcript | the sender writes what it sends; a naive all-sessions grep produces a false positive |
| Same grep excluding the sender's file | 0 | the payload really is absent at the destination |
| Grep a string known to be in B's transcript ("<session B first prompt>") | found | the grep is not blind to that file |
| Grep the marker in base64 and UTF-16LE | 0 | not an encoding artefact |
| Search the entire .claude tree, plus .claude.json and its send-time backup | 0 | not stashed in a side store we know of |
| Count same-day records in a session that did receive a prompt that day | 80 | the "0 records today" reading is real, not a query fault |
⚠ Note for triage — one of our own earlier conclusions was wrong and may be echoed elsewhere. Our
first report stated the payload is *"stored encoded, so a marker grep reads 0 for never-arrived AND for
arrived-and-working."* That is refuted by §3.1: the content is plaintext in the enqueue record. A
plaintext grep is a valid instrument here, and 0 genuinely means never enqueued.
---
6 · Regression window
| when (local +0800) | event |
|---|---|
| 2026-08-11 21:56 | queue enqueue/dequeue working (§3.1) |
| night of 2026-08-11 | a cross-session message is received normally by another session |
| 2026-08-12 06:47 | .claude/settings.json rewritten |
| 2026-08-12 06:48 | break time reported independently in #86069 (18:48 ET) |
| 2026-08-12 14:08 | our workflow switches to a file-based workaround — the send route has already failed |
| 2026-08-14 04:57Z | still failing on 1.30096.1.0 |
The settings.json rewrite one minute before the reported break is suggestive given that1.28929.0 was itself a settings/history persistence change. We are not claiming causation — we
report it because the file's contents are unremarkable (see §7) and only its write time is notable.
---
7 · What we ruled out locally
- Our own config.
settings.jsonexplicitly permitsmcp__ccd_session_mgmt. Both configured hooks
are PreToolUse matching Agent and Bash|Write|Edit — neither matches the messaging tool.
- A third-party CLI install. Unrelated tooling was installed on this machine at
2026-08-12 19:16,
more than five hours after the failure was already measured. Timeline excludes it.
- Machine-specific cause. #86069 reports the same symptom on a different machine beginning the same
day, which no local install of ours could affect.
- A broken deploy of the app itself. The session wakes on cue, so IPC/notification is alive.
---
8 · Relationship to existing issues
- #86069 — Windows/MSIX, reports success, target never responds. Closest. It states the message
is written as a last-prompt record and appears in the composer. We cannot reproduce that half: we
see no record written anywhere. Either two failure modes share a symptom, or the composer copy lives
somewhere our filesystem search does not reach (we could not inspect the running UI).
- #84945 — inbox socket fails to bind for one of two identical sessions. **A socket that never
binds would explain "wakes but never enqueues" exactly.** We suggest checking these together.
- #86319 — delivered to transcript but never processed. Not us — nothing is delivered.
- #86014 / #86370 — success reported, never delivered. Same first half; neither records the
permanent isRunning: true.
- #86279 / #86138 — hung/phantom turn. Closest on the wedge, filed without the transcript measurement.
A discriminator triage can use cheaply: *does a queue-operation:"enqueue" record appear in the
target's .jsonl?* It separates not delivered from delivered and stuck in one grep.
---
9 · Impact
- The failure is silent in the worst direction: the sender is told it succeeded. Any multi-session
workflow will record a handoff that never happened.
- Each probe costs a session — the target is left wedged
isRunning: trueand has to be abandoned
and recreated. That makes re-testing after each release expensive.
- Our workaround requires a human in the loop on every handoff: write the payload to a file, and have
a person paste one line into the target chat. It works 100% of the time, which further localises the
fault to the delivery/enqueue path rather than to the target session's health.
---
10 · Suggested diagnostics
- Instrument the path between "send accepted" and "enqueue written". **The wake fires and the enqueue
does not**, so the failure is between them.
- Check whether the enqueue write is attempted and silently fails under **MSIX/AppContainer file
virtualization** — 1.28929.0 changed persistence, and this app's %LOCALAPPDATA% view differs
between the packaged app and an ordinary user shell on this machine.
- Make
send_messagereport the destination-side result rather than acknowledging the request.
Today's success string is indistinguishable from a total delivery failure.
- Ensure a woken session that finds nothing to dequeue returns to idle instead of remaining
isRunning: true forever.
---
11 · What we could NOT check — stated so nobody assumes it was covered
- ⛔ We could not inspect the running UI. #86069's central claim is that the message *appears in the
target's input composer*. Every measurement above is filesystem-side. If the composer holds a copy
that is never persisted, our "no record written" finding and #86069's "written as a last-prompt
record" are both true of different layers — and that would make the composer the only place the
payload exists. A user with the window open can settle this in one look; we could not.
- ⛔ We did not identify what rewrites the target's transcript file at the send instant. Its mtime
advances while its record count does not change. Something opens and writes that file and adds
nothing — that write is probably the cheapest place to attach a breakpoint.
- ⛔ We could not read the packaged app's own view of
%LOCALAPPDATA%. On this machine the MSIX
app's AppData is virtualized and is not the same view an ordinary user shell sees, so a store we
searched and found empty may not be the store the app actually wrote to. This is the single most
likely way our negative results could be wrong, and it is also why suggestion §10.2 is our lead
hypothesis rather than a conclusion.
- ⛔ We have exactly one confirmed cross-session delivery example on disk (
2026-07-25) carrying the
From {sender title} envelope. We did not establish that every delivery is serialised identically, so
§3.1 should be read as "this is how at least one real delivery was stored" rather than as a schema.
---
Reported by: a user running two long-lived local sessions in one project directory.
Everything above is measured on this machine at 1.30096.1.0; command outputs available on request.
Showing cached comments. Read the full discussion on GitHub ↗
4 Comments
⛔ Correction from the reporter — my central claim above is WRONG, and the corrected version is narrower and more useful
The message IS delivered and IS rendered in the target session. I had only filesystem evidence when I
filed this; I have since seen the target's window. The original claim — *"the prompt is never
enqueued / never arrives"* — is refuted. Please read the report above with this correction applied.
What the UI actually shows
In the target session, below its own last assistant message, the delivered message appears as a
rendered message block attributed to the sending session:
…followed by a running spinner. So delivery, attribution and rendering all work. This is closer to
#86069 than I stated in §8 — though note it renders as a message block in the conversation, not in the
composer.
The real defect: it is delivered and rendered, but NOTHING IS EVER PERSISTED
Everything below is measured on the target session, after the message was visibly on screen:
| probe | result |
|---|---|
| transcript records dated the day of the send | 0 |
|
queue-operationrecords for the delivered message | 0 — noenqueue, nodequeue|| the message body anywhere on disk (plain / base64 / UTF-16) | 0 |
| every timestamp in the target transcript | all from 3 days earlier, none from the send day |
|
lastActivityAt| froze at the send instant and never advanced again — including across the session starting and later stopping || the only line appended |
{"type":"mode","mode":"normal","sessionId":"…"}— and it carries no timestamp at all || session state afterwards | ran with a spinner, then returned to
isRunning: false, having produced and persisted nothing |⇒ The in-memory/UI path is healthy. The persistence path is what fails. The session receives the
message, renders it, begins a turn, and no durable record of any of it is ever written.
Why this framing matters for triage
1.28929.0MSIX persistence change named in #86069 — that release's ownchangelog covers "failing to save chat history, settings, and scheduled tasks." This looks like the
same write path failing for delivered messages.
silently fails under MSIX/AppContainer virtualization. That would explain the render, the spinner, the
frozen
lastActivityAt, the absent records, and the turn ending with no output — in one fault.delivery wrote a plaintext
queue-operation:"enqueue"record into the target's transcript carrying themessage body, followed by a
dequeue~200 ms later. That record is now never written. So theworking/broken diff is real; I mis-attributed it to delivery rather than to persistence.
transcript, the state store and its backups are all clean. Only the running window shows the truth.
Any automation that verifies delivery by reading the transcript — which is the only method available to
a non-interactive agent — will conclude the message was lost. That is arguably the more damaging half
of this bug: not that messages fail, but that they succeed invisibly and then evaporate.
Net effect for a user
The message is delivered and read, and then disappears — there is no record of it in the session's
history, so it is gone on reload and invisible to anything but a human looking at the window at the time.
Apologies for the incorrect framing in the original report. Corrected within a few minutes of obtaining
the one piece of evidence I lacked.
Addendum — the regression window pinned to a local package-deployment timestamp
Everything below is from this machine's
Microsoft-Windows-AppXDeploymentServer/Operationallog and itsown transcripts, so it is independent of #86069's reported break time — and it lands in the same minutes.
Package deployment history on this machine (local time, UTC+8)
| version | first deployment event | last event |
|---|---|---|
|
1.25927.0.0| 2026-08-09 02:34 | 2026-08-10 10:31 ||
1.26832.0.0| 2026-08-09 02:34 | 2026-08-12 07:14 ||
1.28929.0.0| 2026-08-12 06:33:12 | 2026-08-14 05:21 ||
1.30096.0.0| 2026-08-14 04:02 | 2026-08-14 12:35 ||
1.30096.1.0| 2026-08-14 12:22 | 2026-08-14 12:52 |Correlation
The last known-good delivery is ~8.5 hours before
1.28929.0.0was deployed here, and the failure isfirst evidenced ~7.5 hours after it. The regression window contains that deployment.
Two alternative causes checked and excluded
KB5120708,KB5121003,KB5123304all installed 2026-08-11. **Excluded:cross-session delivery was still working at
2026-08-11 21:56:39, after those updates.** (Get-HotFixreports date only, so this is not airtight to the hour — but it is the wrong side of a working
measurement.)
2026-08-12 19:16— **more than five hoursafter the failure had already been measured.**
One observation that argues against a blanket filesystem-permission cause
The target session's transcript was appended to at
2026-08-14 13:34— a{"type":"mode","mode":"normal"}record, written after the failed delivery. Disk has 183 GB free, and anordinary process can create and delete files in that directory right now.
⇒ The app can still write to that exact file. So this does not look like the OS refusing writes
wholesale; it looks like the delivered-message record specifically never being written. That should
narrow where to look.
⚠ Note also that the
moderecord it did write carries no timestamp field, whereas the olderqueue-operationrecords in the same file all do — in case that is meaningful to whoever owns this code.⛔ Second correction from the reporter — this may not be a regression at all, and the report's framing is wrong
Since filing, I found the documented platform matrix. From the cross-session messaging docs, under Availability:
This machine is native Windows. So the honest reading is that I reported a regression on a platform
where the feature is not offered. Please re-read the report above with that applied.
Confirmed on this machine — the feature is not merely failing, it is not enabled
The docs state that a session with messaging enabled exports its inbox socket to hooks and Bash. On this
machine, in a session where the send tool is present and returns success:
Control: 18 other
CLAUDE_*variables are exported in the same shell, so the environment isreadable and the absence is real. ⇒ No inbox socket is bound. There is nothing to deliver to.
I also checked the four variables the docs name as switching feature-flag evaluation off
(
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC,DISABLE_TELEMETRY,DO_NOT_TRACK,DISABLE_GROWTHBOOK).None is set — not in the environment, not in any settings file's
envmap. So the feature is off fora reason other than local opt-out.
⚠ But it demonstrably WORKED on this same machine, which is the part I cannot explain
This is why I filed a regression rather than a support question, and I still think it is worth a look:
the documented
From {sender session title}envelope, stored as a plaintextqueue-operation:"enqueue"record.successful delivery**, and unrelated tooling installed on 08-12 postdates the failure by five hours.
⇒ Either the feature was reaching native Windows unintentionally and that was closed, or a flag
evaluation changed. Given the docs describe it as flag-gated, a flag change is the simplest fit — and
it would explain why an unrelated reporter broke the same day, and why a restart and three app upgrades
since have changed nothing.
⭐ The defect that survives regardless of which of those it is
send_messagereturns a success string on a platform where the feature is not enabled.…while no socket is bound, nothing is queued, nothing is delivered, and the target session is left
running with no record. A caller cannot distinguish "unsupported platform" from "delivered".
⇒ Suggested fix, independent of the platform question: when no inbox socket is bound, the send should
fail loudly — refuse with "cross-session messaging is not available on this platform" rather than
acknowledge. Any workflow that hands work between sessions will otherwise record handoffs that never
occurred, which is how this cost us two days of misdiagnosis.
Corrections to my own earlier comments, for anyone triaging
rendered on screen.** Filesystem-side checks cannot see that.
1.28929.0.0deployment timestamp. **That correlationis real but is now a weaker claim** than the platform-availability explanation, and I would not lead
with it.
— a working delivery stores
contentin plaintext. That part of the original report stands.Apologies for the noise. Leaving the issue open because of the silent-success behaviour, which is a real
defect on any platform; if the platform gap is intentional and that is the whole story, please close it.
CLAUDE_CODE_MESSAGING_SOCKET = <UNSET>
CLAUDE_CODE_MESSAGING_TOKEN = <UNSET>
Bro did u test changing those to something your agent thought of? maybe the temp fix is to create a socket for communications?