-
-
Notifications
You must be signed in to change notification settings - Fork 80.7k
[Bug] WebChat: optimistic USER messages are lost (not just hidden) when chat.send returns before the durable transcript lands — full-replace history reconcile drops them #86946
Copy link
Copy link
Closed as not planned
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.ClawSweeper needs live local, crabbox, or manual validation to confirm this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:data-lossCan lose, corrupt, or silently drop user/session/config data.Can lose, corrupt, or silently drop user/session/config data.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.Good issue quality with a plausible reproduction path needing some confirmation.staleMarked as stale due to inactivityMarked as stale due to inactivity
Description
Metadata
Metadata
Assignees
Labels
P1High-priority user-facing bug, regression, or broken workflow.High-priority user-facing bug, regression, or broken workflow.clawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.ClawSweeper needs live local, crabbox, or manual validation to confirm this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:data-lossCan lose, corrupt, or silently drop user/session/config data.Can lose, corrupt, or silently drop user/session/config data.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.Good issue quality with a plausible reproduction path needing some confirmation.staleMarked as stale due to inactivityMarked as stale due to inactivity
Type
Fields
Priority
None yet
[Bug] WebChat: optimistic USER messages are lost (not just hidden) when
chat.sendreturns before the durable transcript lands — full-replace history reconcile drops themOpenClaw version: 2026.5.22 (
a374c3a)Component: Control UI / WebChat (
ui/src/ui/controllers/chat.ts,ui/src/ui/app-gateway.ts)Severity: High — silent message loss on the primary control surface (not merely a display glitch)
Summary
A user message submitted in WebChat is shown optimistically, then disappears ~1 minute later and is never processed by the agent. Unlike the previously-fixed assistant/streaming cases, here the user message is lost: it never reaches a durable session transcript and no agent turn ever runs for it, so the user believes they sent something and the agent simply never replies.
This persists on 2026.5.22 after the incremental-history-merge work in #66332 (closed COMPLETED) — that fix addressed the assistant/streaming full-replace race, but the optimistic user-send path is still vulnerable.
Root cause (from runtime behavior)
chatMessagesand callschat.send.chat.sendreturns"started"quickly (well before the user message is durably written into the session transcript thatchat.historyreads from).chat.historyreload full-replaceschatMessageswith canonical history. Because the durable user transcript hasn't caught up, the optimistic user bubble has no match in the returned history and is dropped.This is the same full-replace reconcile race described in the #66316 / #66332 / #83949 cluster, but for user messages on the send path rather than assistant messages on the terminal-event path.
Reproduction (live, captured on 2026.5.22)
chat.sendaccepted and returns in ~200ms:chat.historyreconcile.…/agents/<agent>/sessions/*.jsonl, and no agent turn / turn-maintenance runs for it — i.e. themessage was genuinely lost, not just hidden. (In our capture the only subsequent activity in the
session was an unrelated scheduled heartbeat turn.)
Reproducibility is timing-dependent (the gap between
chat.send"started" and the durable transcript write); it shows up reliably when the gateway is busy (e.g. context-engine compaction running, which our logs show firing right after the send).Expected behavior
A submitted user message must never be silently lost. Either:
chat.historyreconcile until the durabletranscript confirms it, and/or
chat.sendmust durably persist the user message before signaling, so the subsequent historyreload includes it.
Known-good local fix (happy to PR)
We patched the Control UI to track pending local user messages keyed by
runId/idempotencyKey,tag the optimistic bubble with metadata, and preserve pending bubbles through
chat.historyreconciliation, clearing them only when canonical history includes the durable user message or when
chat.sendfails. This resolves the loss in our environment. Conceptually it's the user-message analogof the incremental-merge approach from #66332. We can open a PR if useful.
Related