openclaw - 💡(How to fix) Fix [Bug]: Webchat messages stored twice in session — duplicate bubbles in Control UI [1 comments, 2 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#72671Fetched 2026-04-28 06:33:33
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
closed ×1commented ×1labeled ×1unsubscribed ×1

Bug: Every user message sent via the Control UI (webchat) is stored twice in the session .jsonl transcript, creating duplicate chat bubbles in the UI.

Root Cause: Each webchat message creates two separate user-role messages that share the same parentId (fork from the same parent):

Metadata envelope — emitUserTranscriptUpdate stores a bare text message with raw sender metadata: Copy Sender (untrusted metadata): { "label": "openclaw-control-ui", "id": "openclaw-control-ui" } Clean user text — The agent runner stores the actual user message: Copy [Mon 2026-04-27 08:21 GMT] Are there any sessions running in my openclaw? Both share the same parent ID → fork in the conversation tree → Control UI renders both → two bubbles per message.

Evidence: Analysed a live session .jsonl — found 12 fork points, each with 2 sibling user messages (metadata envelope + actual text). Happens for every webchat message.

Expected: Only one user message per actual input. Metadata should either be a property on the single message or marked hidden so the UI skips it.

Env: OpenClaw 2026.4.24, channel: webchat

Root Cause

Root Cause: Each webchat message creates two separate user-role messages that share the same parentId (fork from the same parent):

Code Example

The other sibling contains the actual user text: [Mon 2026-04-27 08:21 GMT] Are there any sessions running in my openclaw?
The Control UI renders both siblings as separate chat bubbles, causing every message to appear duplicated.

### OpenClaw version

OpenClaw 2026.4.24

### Operating system

Debian GNU/Linux 12 (bookworm) inside Docker container; host kernel Linux 6.8.0-107-generic (Ubuntu)

### Install method

_No response_

### Model

glm-5.1

### Provider / routing chain

BrowserTraefik reverse proxy (host)Gateway container (local mode, port 18789)Ollama cloud API

### Additional provider/model setup details

_No response_

### Logs, screenshots, and evidence
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

Bug: Every user message sent via the Control UI (webchat) is stored twice in the session .jsonl transcript, creating duplicate chat bubbles in the UI.

Root Cause: Each webchat message creates two separate user-role messages that share the same parentId (fork from the same parent):

Metadata envelope — emitUserTranscriptUpdate stores a bare text message with raw sender metadata: Copy Sender (untrusted metadata): { "label": "openclaw-control-ui", "id": "openclaw-control-ui" } Clean user text — The agent runner stores the actual user message: Copy [Mon 2026-04-27 08:21 GMT] Are there any sessions running in my openclaw? Both share the same parent ID → fork in the conversation tree → Control UI renders both → two bubbles per message.

Evidence: Analysed a live session .jsonl — found 12 fork points, each with 2 sibling user messages (metadata envelope + actual text). Happens for every webchat message.

Expected: Only one user message per actual input. Metadata should either be a property on the single message or marked hidden so the UI skips it.

Env: OpenClaw 2026.4.24, channel: webchat

Steps to reproduce

  1. Start a fresh OpenClaw instance with the webchat channel enabled
  2. Open the Control UI in a browser
  3. Send any message via the webchat input
  4. Observe: the message appears as two separate chat bubbles in the UI
  5. Inspect the session .jsonl file in <dataDir>/agents/main/sessions/ — each user message creates two user-role entries with the same parentId

Expected behavior

Only one user message per actual input. Metadata should either be a property on the single message or marked hidden so the UI skips it.

Actual behavior

In a webchat session, every user message sent from the Control UI produces two user-role message entries in the session .jsonl file, both sharing the same parentId. For example, in session e1500991-1fb4-4954-8145-6d19f5a1XXXX.jsonl, analysis found 12 fork points where two sibling user messages share a parent:

One sibling contains the raw metadata envelope text: `Sender (untrusted metadata):\n```json\n{"label": "openclaw-control-ui", "id": "openclaw-control-ui"}\n```` The other sibling contains the actual user text: [Mon 2026-04-27 08:21 GMT] Are there any sessions running in my openclaw? The Control UI renders both siblings as separate chat bubbles, causing every message to appear duplicated.

OpenClaw version

OpenClaw 2026.4.24

Operating system

Debian GNU/Linux 12 (bookworm) inside Docker container; host kernel Linux 6.8.0-107-generic (Ubuntu)

Install method

No response

Model

glm-5.1

Provider / routing chain

Browser → Traefik reverse proxy (host) → Gateway container (local mode, port 18789) → Ollama cloud API

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Fork point analysis — 20 fork points found where two user messages share the same parentId. Every fork follows the same pattern: one metadata envelope + one clean user text.

Sample duplicate pair (fork at parentId=bc75024e...):

Copy
// Line 40 — metadata envelope
{
  "type": "message",
  "id": "fda1a6d7...",
  "parentId": "bc75024e...",
  "timestamp": "2026-04-26T22:59:33.751Z",
  "message": {
    "role": "user",
    "content": [{
      "type": "text",
      "text": "Sender (untrusted metadata):\n\n{\"label\":\"openclaw-control-ui\",\"id\":\"openclaw-control-ui\"}\n\n\n[Mon 2026-04-27 00:59 GMT+2] Or not. Cheered to soon"
    }]
  }
}

// Line 45 — clean user text  
{
  "type": "message",
  "id": "deeff732...",
  "parentId": "bc75024e...",
  "timestamp": "2026-04-26T22:59:43.163Z",
  "message": {
    "role": "user",
    "content": [{
      "type": "text",
      "text": "[Mon 2026-04-27 00:59 GMT+2] Or not. Cheered to soon"
    }]
  }
}
Both share parentId=bc75024e..., both are role=user, created 10 seconds apart. The first is the raw emitUserTranscriptUpdate entry (with metadata wrapper), the second is the agent runner's clean entry. The Control UI renders both as separate bubbles.

Impact and severity

No response

Additional information

No response

extent analysis

TL;DR

Modify the emitUserTranscriptUpdate function to include metadata as a property on the single message or mark it as hidden to prevent the UI from rendering it as a separate bubble.

Guidance

  • Identify the source of the duplicate messages: the emitUserTranscriptUpdate function and the agent runner's clean entry.
  • Modify the emitUserTranscriptUpdate function to include the metadata as a property on the single message instead of creating a separate message.
  • Alternatively, mark the metadata message as hidden so the UI skips it.
  • Verify the fix by checking the session .jsonl file for duplicate user-role entries and observing the UI for duplicate chat bubbles.

Example

// Modified message with metadata as a property
{
  "type": "message",
  "id": "deeff732...",
  "parentId": "bc75024e...",
  "timestamp": "2026-04-26T22:59:43.163Z",
  "message": {
    "role": "user",
    "content": [{
      "type": "text",
      "text": "[Mon 2026-04-27 00:59 GMT+2] Or not. Cheered to soon"
    }],
    "metadata": {
      "label": "openclaw-control-ui",
      "id": "openclaw-control-ui"
    }
  }
}

Notes

This solution assumes that the emitUserTranscriptUpdate function can be modified to include metadata as a property on the single message. If this is not possible, marking the metadata message as hidden may be a viable alternative.

Recommendation

Apply the workaround by modifying the emitUserTranscriptUpdate function to include metadata as a property on the single message. This approach should prevent the UI from rendering duplicate chat bubbles.

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

Only one user message per actual input. Metadata should either be a property on the single message or marked hidden so the UI skips it.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING