openclaw - ✅(Solved) Fix [Bug]: Control UI webchat duplicates every assistant reply on 2026.4.21 — regression from #5964/#39469 [2 pull requests, 5 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#71992Fetched 2026-04-27 05:36:23
View on GitHub
Comments
5
Participants
3
Timeline
10
Reactions
0
Timeline (top)
commented ×5referenced ×3cross-referenced ×2

Root Cause

Root cause analysis (from prior investigation)

Fix Action

Fixed

PR fix notes

PR #72004: fix(control-ui): stop duplicate-render race on assistant final messages (#71992)

Description (problem / solution / changelog)

Summary

Fixes #71992.

Every assistant reply in the Control UI webchat appears exactly twice on 2026.4.21+. Server transcripts contain one assistant entry per turn — this is a client-side rendering race.

In `ui/src/ui/controllers/chat.ts#handleChatEvent`, both the `final` and `aborted` branches mutate `state.chatMessages` BEFORE clearing `state.chatStream`. Lit batches reactive updates: between the chatMessages mutation and the next render, chatStream still holds the streaming text AND chatMessages contains the committed assistant message, so Lit renders both.

Fix: capture the streamed fallback text into a local, clear chatStream / chatRunId / chatStreamStartedAt FIRST, then mutate chatMessages. The render pass observing the chatMessages change sees chatStream already null, so only the committed message renders.

The reporter cited closed PR #34164 which had this exact swap; that PR was closed for unrelated reasons (mixed-in iOS files), so the fix never landed.

New test

``clears chatStream before appending final message to prevent duplicate-render race`` uses a property accessor on chatMessages that records chatStream's value at the exact moment chatMessages mutates. Asserts chatStream is null at that moment.

Pre-implement audit (skill v6 rules)

RuleStatusNotes
Existing-helper checkPASSNo helper introduced; reordering existing code
Shared-helper-caller checkPASS`handleChatEvent` has callers but the externally-observable contract is unchanged (final state is identical, only the intermediate ordering differs)
Broader-fix rival scanPASSNo open rival PR; closed #34164 was the prior identical attempt that got closed for unrelated reasons

Test plan

  • `pnpm exec vitest run ui/src/ui/controllers/chat.test.ts` — 76/76 pass (74 existing + 2 new)
  • Existing `appends final payload message from own run before clearing stream state` test still passes — final-state contract unchanged
  • `pnpm exec oxfmt --check` — clean
  • `pnpm exec oxlint` — 0 warnings/errors
  • CI green
  • Manual repro: open Control UI webchat, send 3+ messages, confirm no duplicates

Related

  • #5964 (original report, closed as not planned)
  • #39469 (regression, closed)
  • #34164 (prior fix attempt, closed for unrelated mixed-in iOS files)

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • ui/src/ui/controllers/chat.test.ts (modified, +46/-0)
  • ui/src/ui/controllers/chat.ts (modified, +25/-19)

PR #72290: fix(chat): prevent duplicate user message delivery in 2026.4.24 regression

Description (problem / solution / changelog)

Problem

After upgrading to 2026.4.24, identical user messages are occasionally delivered twice to the session (same timestamp, different seq numbers), causing duplicate assistant replies. Affects webchat, WeChat, and potentially all channels.

Root Cause

  1. Primary: Some channel retry paths generate new idempotencyKey per attempt, bypassing the primary dedupe (which uses MessageSid = clientRunId).
  2. Secondary: emitUserTranscriptUpdate user messages lacked idempotencyKey, so even if inbound dedupe worked, the transcript layer couldn't catch duplicates.

Fix

  1. Content-based dedupe fallback (inbound-dedupe.ts): When MessageSid is unavailable, fall back to SHA-256 hash of Body|Timestamp|peerId to catch duplicate messages regardless of ID stability.

  2. Transcript idempotency (chat.ts): Add idempotencyKey: clientRunId to user message entries in emitUserTranscriptUpdate, enabling secondary dedupe at the transcript layer via transcriptHasIdempotencyKey.

Issue

Fixes #72176

Changed files

  • src/auto-reply/reply/inbound-dedupe.ts (modified, +16/-2)
  • src/gateway/server-methods/chat.ts (modified, +3/-0)
  • src/gateway/server-methods/chat.ts.backup (added, +2838/-0)
RAW_BUFFERClick to expand / collapse

Bug description

Every assistant reply in the Control UI webchat appears exactly twice in the chat view. Full duplicate, not streaming fragments.

  • Fresh install of OpenClaw 2026.4.21 via npm
  • /debug system-events off is disabled by default and cannot be toggled
  • Clearing Local Storage + hard refresh temporarily fixes it
  • Bug returns after a few messages
  • Does NOT occur with Telegram channel (same session)

Environment

ItemValue
OpenClaw version2026.4.21
OSmacOS 15.4 (Darwin 25.4.0, arm64)
BrowserChrome + Safari both affected
Gateway modelocal
Modelkimi/kimi-code

Steps to reproduce

  1. Open Control UI at http://127.0.0.1:18789/chat
  2. Send any message
  3. Observe assistant reply appears twice
  4. Refresh page → temporarily fixed
  5. Send a few more messages → duplicates return

Root cause analysis (from prior investigation)

This is a client-side rendering bug, not backend duplication:

  • Server transcript (.jsonl) contains exactly one assistant entry per turn
  • chatStream and chatMessages can both contain the same message simultaneously due to Lit's async batching
  • The fix was identified in PR #34164 (swap update order: clear chatStream before updating chatMessages) but that PR was closed and never merged due to unrelated iOS files being mixed in

Related issues

  • #5964 — original report (closed as not planned)
  • #39469 — regression report (closed)
  • #38061 — chat.history returning delivery-mirror entries
  • #33263 — precursor identifying delivery-mirror transcript entries
  • #34164 — fix PR, closed without merge

Expected behavior

Each assistant turn produces exactly one visible message in the Control UI.

Request

Please either:

  1. Reopen #34164 as a clean PR with just the webchat fix (chat.ts + chat.test.ts), or
  2. Apply the one-line fix directly: clear chatStream/chatRunId before writing to chatMessages in both final and aborted event handlers

extent analysis

TL;DR

The most likely fix is to apply the one-line fix by clearing chatStream/chatRunId before writing to chatMessages in both final and aborted event handlers.

Guidance

  • Review the code changes proposed in PR #34164 to understand the fix, focusing on the update order of chatStream and chatMessages.
  • Verify that the server transcript (.jsonl) contains exactly one assistant entry per turn to confirm the issue is client-side rendering.
  • Test the fix by applying the one-line change to chat.ts and updating chat.test.ts accordingly.
  • Check if the issue persists after applying the fix by sending multiple messages and observing the chat view.

Example

No code snippet is provided as the issue does not contain explicit code, but the fix involves modifying the chat.ts file to clear chatStream/chatRunId before updating chatMessages.

Notes

The fix may not be applicable if there are other underlying issues with the client-side rendering or if the PR #34164 had other unintended consequences.

Recommendation

Apply the workaround by clearing chatStream/chatRunId before writing to chatMessages in both final and aborted event handlers, as this is a targeted fix for the identified client-side rendering bug.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Each assistant turn produces exactly one visible message in the Control UI.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: Control UI webchat duplicates every assistant reply on 2026.4.21 — regression from #5964/#39469 [2 pull requests, 5 comments, 3 participants]