openclaw - ✅(Solved) Fix Control UI chat flickers sent user messages, they disappear briefly then reappear [1 pull requests, 4 comments, 5 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#66207Fetched 2026-04-14 05:38:50
View on GitHub
Comments
4
Participants
5
Timeline
6
Reactions
1
Timeline (top)
commented ×4cross-referenced ×1subscribed ×1

In OpenClaw Control UI chat, a just-sent user message appears immediately, then disappears for about 1 to 2 seconds, then reappears.

This appears to have started after the latest update.

Root Cause

Likely root cause

Control UI is showing an optimistic local user message first, then a later chat.history refresh replaces the full message list before the persisted server-backed version is reconciled cleanly.

Fix Action

Fixed

PR fix notes

PR #66271: Control UI: avoid chat flicker on session reload

Description (problem / solution / changelog)

Summary

  • Problem: Control UI user messages can disappear briefly after send in 2026.4.12.
  • Why it matters: the chat transcript visibly flickers on every send, which makes the UI feel unreliable.
  • What changed: skip the session.message-triggered history reload when it is only echoing the active run's own optimistic user message, and add a regression test.
  • What did NOT change (scope boundary): no broader optimistic-message reconciliation or transcript merge behavior.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #66207
  • Related #66207
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: 2026.4.12 added a Control UI session.message handler that unconditionally reloaded chat.history for the active session. The chat UI already renders the user's message optimistically, and loadChatHistory replaces chatMessages wholesale, so an early reload can briefly swap in a stale transcript snapshot before persistence catches up.
  • Missing detection / guardrail: there was no regression test covering an active optimistic user message during a session.message echo.
  • Contributing context (if known): 4.11 did not have this session.message reload path in Control UI.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: ui/src/ui/app-gateway.sessions.node.test.ts
  • Scenario the test should lock in: while chatRunId is active, a same-session session.message event carrying a user message should not trigger loadChatHistory.
  • Why this is the smallest reliable guardrail: the regression was introduced in the Control UI gateway event handler, so that seam isolates the behavior directly.
  • Existing test that already covers this (if any): none
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • Just-sent user messages remain visible continuously instead of disappearing briefly before transcript persistence catches up.

Diagram (if applicable)

Before:
[user send] -> [optimistic user message visible] -> [session.message reloads history] -> [stale history replaces optimistic row] -> [later history reload restores message]

After:
[user send] -> [optimistic user message visible] -> [session.message user echo is ignored during active run] -> [message stays visible]

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: local UI test runner
  • Model/provider: N/A
  • Integration/channel (if any): Control UI webchat
  • Relevant config (redacted): default local dev config

Steps

  1. Start from the Control UI chat send flow with an active chatRunId.
  2. Receive a session.message event for the same session containing a user message echo.
  3. Observe whether the handler reloads chat.history.

Expected

  • The optimistic local user message remains visible and the handler skips the redundant reload.

Actual

  • The focused regression test now passes and confirms the reload is skipped in that case.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios: ran pnpm test ui/src/ui/app-gateway.sessions.node.test.ts and confirmed the new regression test plus existing session-message coverage pass.
  • Edge cases checked: same-session events still reload when no active run is present; other-session events remain ignored.
  • What you did not verify: manual browser reproduction in a running Control UI instance.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: a non-local user session.message event could be delayed if it arrives while chatRunId is active and only exposes role: user.
    • Mitigation: the guard is narrowly limited to the active run window and only the user-echo case that is already rendered optimistically; final assistant events and other transcript reload paths still run.

Changed files

  • ui/src/ui/app-gateway.sessions.node.test.ts (modified, +61/-0)
  • ui/src/ui/app-gateway.ts (modified, +55/-2)
RAW_BUFFERClick to expand / collapse

Summary

In OpenClaw Control UI chat, a just-sent user message appears immediately, then disappears for about 1 to 2 seconds, then reappears.

This appears to have started after the latest update.

Symptoms

When sending a message in Control UI:

  • the message lands in the chat area immediately
  • then vanishes briefly
  • then pops back into the transcript about 1 to 2 seconds later

This was observed repeatedly, including on plain text messages.

Expected behavior

A sent user message should remain visible continuously after local send, without disappearing during reconciliation.

Actual behavior

The message appears optimistically, then disappears, then reappears after the server-backed transcript catches up.

Repro

  1. Open Control UI chat
  2. Send a normal text message
  3. Watch the just-sent message in the transcript
  4. Observe it appear immediately, disappear briefly, then reappear 1 to 2 seconds later

Evidence / investigation notes

This looks like a front-end optimistic-message reconciliation problem rather than a transport failure.

Relevant Control UI runtime behavior observed locally in dist/control-ui/assets/index-*.js:

  • the send path appends the user message locally to chatMessages immediately
  • chat.send is then issued to the gateway
  • later, the UI refresh path calls chat.history
  • the returned history replaces chatMessages

The local optimistic user message does not appear to carry a stable persisted message id, and display keys fall back to combinations like timestamp/index when no stable id is present.

That makes it plausible for the optimistic local message and the later persisted/history-backed message to be treated as different entries rather than a clean reconciliation of the same message.

Likely root cause

Control UI is showing an optimistic local user message first, then a later chat.history refresh replaces the full message list before the persisted server-backed version is reconciled cleanly.

That causes the optimistic copy to disappear briefly, then the history-backed copy to show up shortly after.

Suggested fix

Possible approaches:

Preferred:

  • assign optimistic user messages a stable client id and reconcile them against the persisted history message

Also reasonable:

  • merge chat.history results with pending optimistic messages instead of replacing the full array blindly

Less ideal:

  • reduce or defer full-history replacement immediately after send

Environment

  • OpenClaw Control UI
  • User reports this started after the latest update

extent analysis

TL;DR

Assigning a stable client ID to optimistic user messages and reconciling them against the persisted history message is the most likely fix.

Guidance

  • Review the chatMessages update logic in dist/control-ui/assets/index-*.js to ensure that optimistic messages are properly reconciled with the server-backed transcript.
  • Consider implementing a merge of chat.history results with pending optimistic messages to prevent replacement of the full array.
  • Verify that the issue is resolved by testing the chat functionality after applying the suggested fix.
  • Investigate the latest update changes to identify the root cause of the introduced issue.

Example

// Pseudocode example of assigning a stable client ID
const optimisticMessage = {
  id: generateStableClientId(),
  text: 'User message',
  // ...
};

// Reconcile optimistic message with persisted history message
const historyMessage = chat.history.find((message) => message.id === optimisticMessage.id);
if (historyMessage) {
  // Update optimistic message with persisted history message
  optimisticMessage.text = historyMessage.text;
  // ...
}

Notes

The suggested fix assumes that the issue is related to the reconciliation of optimistic user messages with the persisted history. However, the root cause may be more complex, and additional investigation may be required.

Recommendation

Apply the workaround of assigning a stable client ID to optimistic user messages and reconciling them against the persisted history message, as it is the most likely fix and has a clear implementation path.

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

A sent user message should remain visible continuously after local send, without disappearing during reconciliation.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING