-
-
Notifications
You must be signed in to change notification settings - Fork 80.7k
[Bug]: iOS Chat briefly duplicates final assistant reply before history reconciliation #98116
Copy link
Copy link
Closed
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.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.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.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: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Description
Metadata
Metadata
Assignees
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.ClawSweeper found an open linked pull request for this issue.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.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.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: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Priority
None yet
Summary
iOS Chat can briefly render the same assistant final reply twice when a live
chat.finalevent and the canonicalsession.messagetranscript event both arrive for the same turn. After a later history refresh, one copy disappears, so the UI looks like it duplicated and then deleted a final answer.Real environment observed
2026.6.11-beta.2Private setup codes, auth tokens, and the exact user transcript are intentionally omitted.
User-visible symptom
A single assistant response appears twice in the iOS Chat transcript. A moment later one copy disappears after the transcript/history state catches up. This makes the mobile chat look unstable even though the Gateway eventually stores only one final assistant turn.
Source-level repro on current main
The duplicate is consistent with the current shared iOS/macOS chat view-model event flow:
OpenClawChatViewModel.handleChatEventhandleschat.state == "final"by callingappendFinalChatMessageIfPresent(chat)so the final answer is visible immediately.handleSessionMessageEventas the canonicalsession.messagetranscript row.dedupeMessagesusesmessageIdentityKey(for:), which includes the message timestamp and content metadata.chat.finalrow and canonicalsession.messagerow can carry the same assistant text but different timestamps or content metadata, so they do not dedupe before the laterchat.historyrefresh reconciles the transcript.That sequence produces a transient duplicate final assistant row, followed by one row disappearing when history applies.
Expected behavior
The iOS Chat UI should show one assistant final row for a turn, whether the live final event arrives before or after the canonical session transcript event.
Actual behavior
The UI can temporarily show two identical final assistant rows for one turn, then remove one during history reconciliation.
Scope / non-goals
OpenClawChatUIreconciliation between livechat.finaland canonicalsession.messageevents.OKon separate turns.Proposed fix
Treat assistant rows inserted from live
chat.finalas provisional for the current turn. If the canonicalsession.messagefor the same assistant content arrives, adopt/replace the provisional row instead of appending a second visible row. If the canonicalsession.messagearrives first, skip the later matching live final row for that same turn. Keep the matching scoped to messages after the latest user turn so a stale provisional answer from an earlier turn cannot consume a later identical reply.