[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)

Status Open
Maintainer reply None cached
Activity 6 comments · opened Aug 14, 2026
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:

  1. the session wakesisRunning flips false → true and lastActivityAt advances to the send instant;
  2. it runs for roughly 1–2 seconds;
  3. no queue-operation record is written, the transcript does not grow, and no turn is produced;
  4. the session is left isRunning: true and does not recover on its own.

The distinguishing measurement in this report: when this feature worked, delivery wrote a
queue-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.0PackageFullName: 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_messageMessage sent to session local_<session-B-id> ("Session B")
  • get_sessionisRunning: true, lastActivityAt: "2026-08-14T04:57:36.230Z" (was 2026-08-11T21:56Z)
  • target transcript: 10 lines before, 10 lines after
  • records dated 2026-08-14 in the target transcript: 0
  • queue-operation records dated today: 0 — no enqueue, no dequeue
  • transcript file mtime advances to 12:57:37 +0800 (= the send instant) while gaining no records
  • .claude.json and 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

  1. Session A and session B, both ordinary local interactive sessions. Leave B idle and finished.
  2. From A, call send_message at B with a unique marker string in the body.
  3. Read the tool's return value. (It will claim success.)
  4. get_session(B) → observe isRunning: true and lastActivityAt at the send instant.
  5. Grep B's transcript .jsonl for queue-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 that
1.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.json explicitly permits mcp__ccd_session_mgmt. Both configured hooks

are PreToolUse matching Agent and Bash|Write|Editneither 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).

  • #84945inbox 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: true and 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

  1. Instrument the path between "send accepted" and "enqueue written". **The wake fires and the enqueue

does not**, so the failure is between them.

  1. 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.

  1. Make send_message report the destination-side result rather than acknowledging the request.

Today's success string is indistinguishable from a total delivery failure.

  1. 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

  1. 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.

  1. 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.

  1. 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.

  1. 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.

View original on GitHub ↗

4 Comments

Neverbet · 17 days ago

⛔ 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:

💬 Message from <sender session title>
PING-…-0457 — connectivity test only, from <sender>.
⛔ THIS IS NOT A PROMPT AND THERE IS NO WORK ATTACHED. Do nothing. …

…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-operation records for the delivered message | 0 — no enqueue, no dequeue |
| 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. It is consistent with the 1.28929.0 MSIX persistence change named in #86069 — that release's own

changelog covers "failing to save chat history, settings, and scheduled tasks." This looks like the
same write path failing for delivered messages.

  1. A plausible single cause for all observed symptoms: the turn blocks on a persistence write that

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.

  1. The comparison in §3 of the report still stands and is the useful part. When this worked, a

delivery wrote a plaintext queue-operation:"enqueue" record into the target's transcript carrying the
message body, followed by a dequeue ~200 ms later. That record is now never written. So the
working/broken diff is real; I mis-attributed it to delivery rather than to persistence.

  1. A warning for anyone reproducing this: every filesystem-side check reports "never arrived." The

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.

Neverbet · 17 days ago

Addendum — the regression window pinned to a local package-deployment timestamp

Everything below is from this machine's Microsoft-Windows-AppXDeploymentServer/Operational log and its
own 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

2026-08-11 21:56:39   last observed WORKING enqueue/dequeue pair in a target transcript
2026-08-12 06:33:12   1.28929.0.0 first deployed on this machine
2026-08-12 06:47      ~/.claude/settings.json rewritten
2026-08-12 06:48      break time independently reported in #86069 (18:48 ET)
2026-08-12 14:08      this user's workflow had already switched to a manual workaround
2026-08-14 05:37      still failing on 1.30096.1.0

The last known-good delivery is ~8.5 hours before 1.28929.0.0 was deployed here, and the failure is
first evidenced ~7.5 hours after it.
The regression window contains that deployment.

Two alternative causes checked and excluded

  1. Windows updates. KB5120708, KB5121003, KB5123304 all installed 2026-08-11. **Excluded:

cross-session delivery was still working at 2026-08-11 21:56:39, after those updates.** (Get-HotFix
reports date only, so this is not airtight to the hour — but it is the wrong side of a working
measurement.)

  1. Unrelated third-party tooling installed by this user at 2026-08-12 19:16 — **more than five hours

after 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 an
ordinary 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 mode record it did write carries no timestamp field, whereas the older
queue-operation records in the same file all do — in case that is meaningful to whoever owns this code.

Neverbet · 17 days ago

⛔ 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:

Operating system: available on macOS and Linux, including Linux inside WSL 2. Claude Code doesn't offer cross-session messaging on native Windows.

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:

CLAUDE_CODE_MESSAGING_SOCKET = <UNSET>
CLAUDE_CODE_MESSAGING_TOKEN  = <UNSET>

Control: 18 other CLAUDE_* variables are exported in the same shell, so the environment is
readable 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 env map. So the feature is off for
a 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:

  • 2026-07-25 — a cross-session delivery is recorded in a target transcript on this machine, carrying

the documented From {sender session title} envelope, stored as a plaintext
queue-operation:"enqueue" record.

  • It went on working until 2026-08-11, then stopped, and has never worked since.
  • Nothing local changed in that window that we can find: **the Windows updates on 08-11 predate the last

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_message returns a success string on a platform where the feature is not enabled.

Message sent to session local_… ("<target title>")

…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

  1. My first comment said the message is never delivered. **A screenshot of the target window showed it

rendered on screen.** Filesystem-side checks cannot see that.

  1. My second comment pinned the regression to the 1.28929.0.0 deployment timestamp. **That correlation

is real but is now a weaker claim** than the platform-availability explanation, and I would not lead
with it.

  1. The earlier statement that the payload is "stored encoded" (from an internal note of ours) is wrong

— a working delivery stores content in 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.

TomerBrosh · 16 days ago

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?

Showing cached comments. Read the full discussion on GitHub ↗