Desktop: Submitted Message Becomes "Queued" and Is Lost or Mishandled
Corrected 2026-08-29. The first version of this report claimed the message was never enqueued and could therefore never fire. That was wrong, and it was built on the wrong session. What the reporter actually observed is below: the message does reach the chip on Enter, it is delivered late, and it arrives behind input typed after it. The measurements have been re-run on the full transcript corpus rather than the 2 percent slice the first version used. Both errors are described at the end.
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?
A message typed into the composer and submitted with Enter goes to the N message queued chip
instead of the conversation. It then takes a long time to enter the chat flow, and when it does
it lands behind messages typed after it. Submission order and delivery order do not match.
Three things are wrong at once, and the third is the one that costs real work:
- The delay is unbounded and unexplained. The chip shows a count and a truncated preview.
It does not say what it is waiting for or how long it has waited.
- Delivery is out of order. A message sitting in the chip is overtaken by later input. The
later message gets answered first, in a context that does not yet contain the earlier one.
- Waiting and lost are the same picture. Nothing distinguishes a message that will arrive
in ten seconds from one that will not arrive at all, so the only way to find out is to wait
and see whether the instruction was ever acted on.
Out-of-order delivery is worse than plain delay. A queued correction that lands after the work
it was meant to redirect is not merely late. The model acts on the later message first, and the
earlier one then arrives looking like a fresh instruction rather than the correction it was.
Measurements
Sessions record queue activity as first-class transcript events, which makes the normal case
measurable:
{"type":"queue-operation","operation":"enqueue","timestamp":"...","content":"..."}
{"type":"queue-operation","operation":"remove","reason":"absorbed_mid_turn","content":"..."}
Normal absorption is fast. Two sessions, same app instance, same minute, both mid-turn:
20:30:19.091 enqueue "You should be adding a table at the end of every cycle"
20:30:19.130 remove absorbed_mid_turn <- 39 ms
20:30:32.755 enqueue "You should be adding a table at the end of each cycle"
20:30:32.775 remove absorbed_mid_turn <- 20 ms
But latency in the same app across the same few minutes spans three orders of magnitude:
20 ms plain typed message
39 ms plain typed message
27 s batch of 13 cross-session messages
34 s batch of 2 cross-session messages
There is no single expected wait a user could learn. The chip in this report stayed up far
longer than any of these, through more than eight minutes in which the session worked normally,
opened two pull requests, and produced more than fifty assistant turn boundaries.
What I could not confirm from logs is the eventual delivery. Searching the full local corpus
for two verbatim fragments of the chip's own preview text returns nothing:
corpus: 16,384 transcripts across 6 profile directories, recursive, no sampling
"do you know what I mean" -> 0 files
"why are you not doing it" -> 0 files
"end of each cycle" -> 4 files <- CONTROL, proves the probe fires
The control matters. A probe that returns zero everywhere is indistinguishable from a broken
probe, so the third pattern is one that must fire, and does. The reporter watched the message
enter the conversation eventually. I am reporting that I could not corroborate that from the
transcripts, not that it failed to happen.
What Should Happen?
- Delivery order should match submission order. A message queued first should be delivered
first, ahead of anything typed after it.
- The chip should say what it is waiting for and how long it has waited.
- There should be a way to deliver the message now rather than waiting an unbounded time.
- If a queued message cannot be delivered, that should surface rather than leaving a chip that
implies it is safely waiting.
Error Messages/Logs
No desktop log is available, which is worth reporting on its own. The Windows MSIX build at this
version writes none I can find:
%APPDATA%\Claude\logs\main*.logexists, nothing written since 2026-08-28.%LOCALAPPDATA%\Claude\Logs\main.loglikewise.- No log of any type newer than 2026-08-28 anywhere under
%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\.
Older rotated logs do contain [LocalSessionManager] flushed held steers andcancelQueuedMessage ... -> cancelled, so this logging exists and is not landing for this
build. Without it a user cannot see which queue holds a waiting message, or why it is waiting.
Steps to Reproduce
No deterministic repro, and I would rather say so than invent one. The conditions:
- Twelve local desktop sessions open in one app instance, each in its own git worktree of the
same repository, several of them exchanging cross-session messages.
- The target session was mid-turn, making continuous tool calls, and had already absorbed
several queued inputs during that same turn in tens of milliseconds.
- A plain sentence was typed and submitted with Enter. No slash command, no
!prefix, no
session switch.
- It went to the chip, stayed a long time, and arrived behind messages typed after it.
The cross-session message traffic may be a factor. Those batches are the only inputs measured
here that took tens of seconds rather than milliseconds, and the affected session was receiving
them throughout.
Claude Code Version
Bundled CLI 2.1.251, desktop app 1.37937.0 (MSIX Claude_1.37937.0.0_x64__pzs8sxrjxfjjc)
Platform
Claude Desktop app
Operating System
Windows 11 Pro, build 10.0.26200
Additional Information
Related, none of them this report:
- #73661 asks for queued messages to be processed sequentially, one message per turn, FIFO.
That request and this bug are the same underlying complaint about ordering.
- #87037 asks for the ordering rule to be documented, noting that plain prompts fold into the
running turn. This was a plain prompt that did not fold in, while an almost identical one in a
sibling session did, 13 seconds earlier.
- #73118 covers long turns blocking queued messages. Adjacent, but does not cover order.
- #81582 covers the chip becoming undismissable when
cancelQueuedMessagefalls through every
strategy because the uuid "exists in none of the manager's queues". Possibly the same desync
seen from the cancel side.
- #77010 and #77451 cover queued messages lost across a session switch. No switch here.
On the two errors in the first version of this report, since both are the kind that survive
review by looking measured:
The first was scope. I searched 321 transcripts and reported a zero. The real corpus is 16,384
across six profile directories, so I had covered about two percent of it while presenting the
result as a corpus-wide census.
The second was attribution. I read the queue events of the wrong session, found the message
absent, and concluded it had never been enqueued anywhere. It had been enqueued in a different
session and absorbed in 20 milliseconds. A zero from the wrong file reads exactly like a zero
from the right one.
3 Comments
Correction: I have rewritten this issue. The original version was wrong on its central claim.
It said the message was never enqueued and could therefore never fire. Two mistakes produced that:
generalized. It had in fact been enqueued in a different session and absorbed in 20 milliseconds.
real corpus is 16,384 transcripts across six profile directories, so I had covered about two
percent of it.
The actual behavior, from the reporter: the message goes to the chip on Enter, takes a long time to
enter the chat flow, and lands behind messages typed after it. That makes this an ordering and
latency bug, not a loss bug. The title and body now say so.
Leaving the record of both errors in the issue rather than quietly editing them out, since a zero
from the wrong file reads exactly like a zero from the right one, and that is worth flagging to
anyone who reads the measurements here.
One consequence for triage: my earlier suggestion that this explains #81582 no longer follows. It
may still be related, but the evidence I offered for it does not support the link.
Here is an image of a stuck queued message
<img width="762" height="136" alt="Image" src="https://github.com/user-attachments/assets/828db4f9-06ac-4bca-98a4-076aee595163" />
Same bar, a different failure: the queue emptied, the chip kept advertising, and I re-uploaded
Environment:
claude-desktop, version2.1.246, Windows 11.I put an image (no text) into the composer and hit Enter while a turn was running. It was delivered. The chip went on showing
1 message queued [Image]for the next five minutes, so I assumed it was stuck and submitted the same image again.Timeline
| Time (UTC) | Record | Detail |
|---|---|---|
| 23:49:10.340 |
queue-operationenqueue| nocontentkey || 23:49:10.340 |
attachmentqueued_command|prompt: [{"type":"image"}],origin.kind: "human",source_uuid: 52fdad7d-...|| 23:49:10.350 |
queue-operationremove,reason: absorbed_mid_turn| queue released it, 10 ms after Enter || 23:49:22.986 | next API request | the image enters the model's context here, 12.6 s after release |
| 23:50:00.281 | a later message | submitted and delivered normally, while the chip still showed 1 queued |
| 23:53:59.102 |
enqueue| I gave up and resubmitted the same image || 23:54:14.621 |
userturn | resubmitted copy lands, 15.5 s later. Chip finally clears |The two copies are byte-identical: sha256
ba4cb9281d6c1e7d..., 319,353 bytes, PNG 1782x1509.The model demonstrably received the first copy. At 23:53:56.942, seventeen seconds before the second copy arrived, it quoted three exact figures off the image and correctly placed a block at the bottom of it. Those figures appear nowhere else in the transcript, in no tool result and no file read.
The queue was never slow. Only the indicator was wrong.
I FIFO-matched every
queue-operationrecord in the session. Zero unmatched removals, final depth zero, depth never above 2.| Window | Duration |
|---|---|
| Longest hold by any queue entry, anywhere in the session | 41.3 s |
| Chip advertising a queued message while the queue was provably empty | 4 min 48.8 s |
| Total time a false or duplicate queue indicator was on screen | 5 min 4.3 s |
Nothing was lost, delayed in the queue, or dropped. The badge and the queue simply came apart, and that gap is the bug.
The mechanism the records point to
Queue audit records carry no identifier. Across 323 transcripts and 33,734
queue-operationrecords there are exactly four key sets, and the union of every key ever present is:No
id, nouuid, no sequence number. The payload does have an identity, since thequeued_commandattachment carriessource_uuid. That id is absent from every queue event.So
content, the message text, is the only thing that can name a particular queued item:| Operation | Count | Carries
content||---|---|---|
|
dequeue| 12,416 | 0 of 12,416. Positional, pops the head. ||
remove| 4,445 | 4,294 of 4,445. Content-addressed, names the item by its text. |An image-only submission enqueues with no
contentkey at all, 431 of 16,873. In this session the correspondence is exact in both directions: 3 of 3 image enqueues carry no content key, 21 of 21 text enqueues do.The collision is a content-addressed
removeof an item with no content to address it by:Thirteen occurrences, across 8 sessions and 2 days, in one user's corpus.
That last step is an inference and I am labelling it as one. A transcript holds no renderer state, so the correlation is complete but it is not the mechanism. Whoever fixes this needs the client code. What is measured is that the queue events give the UI nothing to match an image removal against.
What it cost, since "only the indicator is wrong" was my own understatement
The defect is confined to the indicator. The consequence is not.
[Image]whether the queue is real or stale, so there is no way to tell the two apart from the UI. That is why I waited, and then why I re-sent.Suggestions
enqueue,dequeueandremove, and have the UI retire entries by id. That removes the whole class rather than the image case alone.What the first version got wrong
enqueuetoremove, the queue releasing the item. Entry into the model's context happens at the next API request, 12.6 s later. Worth stating because the two are easy to conflate and the transcript makes only the first one obvious.