openclaw - 💡(How to fix) Fix [Bug]: Control UI / webchat duplicates user message and leaks `Sender (untrusted metadata)` as `openclaw-control-ui` [2 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#72861Fetched 2026-04-28 06:31:15
View on GitHub
Comments
2
Participants
2
Timeline
3
Reactions
1
Author
Timeline (top)
commented ×2cross-referenced ×1

Control UI / webchat can duplicate a single user message into two visible user turns:

  • one normal local/plain user message
  • one echoed user message whose content begins with Sender (untrusted metadata): and whose sender label resolves to openclaw-control-ui

This appears to be a regression after 2026.4.24 / present in 2026.4.24+ builds.

This is not just double ingress from the browser. The current code path can emit two different user-message representations for the same logical turn.

Root Cause

The current runtime appears to have two separate user-turn paths for the same webchat input:

1) Early webchat transcript update path

/root/.nvm/versions/node/v22.22.2/lib/node_modules/openclaw/dist/chat-DznnoAn8.js

  • emitUserTranscriptUpdate() at 2369-2394
  • calls emitSessionTranscriptUpdate({ message: buildChatSendTranscriptMessage(...) })
  • buildChatSendTranscriptMessage(...) at 1263-1270 produces a plain:
    • role: "user"
    • content: params.message

2) Main reply/transcript path with inbound metadata

/root/.nvm/versions/node/v22.22.2/lib/node_modules/openclaw/dist/get-reply-CSQ5BMwG.js

  • buildInboundUserContextPrefix(...) at 1820
  • inbound user context is assembled into prompt/transcript body around 2231-2242
  • transcriptCommandBody is passed onward at 2455-2456 and 2533-2534

Then runner path forwards transcript prompt:

/root/.nvm/versions/node/v22.22.2/lib/node_modules/openclaw/dist/agent-runner.runtime-CbAg9IpO.js

  • CLI path: 732
  • embedded path: 831
  • run dispatch: 3070

3) Transcript update broadcast does not sanitize the visible message

/root/.nvm/versions/node/v22.22.2/lib/node_modules/openclaw/dist/server.impl-CtLS1ywt.js

  • createTranscriptUpdateBroadcastHandler(...) at 9229-9253
  • broadcasts update.message via session.message
  • does not call stripInboundMetadata(...) / stripEnvelopeFromMessage(...)

4) There is already an explicit contract that this metadata must never be displayed

/root/.nvm/versions/node/v22.22.2/lib/node_modules/openclaw/dist/strip-inbound-meta-DaDVfj8b.js

Header comment says OpenClaw-injected inbound metadata blocks are AI-facing only and:

must never surface in user-visible chat history

The sentinel list includes:

  • Conversation info (untrusted metadata):
  • Sender (untrusted metadata):

Fix Action

Fix / Workaround

  • CLI path: 732
  • embedded path: 831
  • run dispatch: 3070

Minimal safe mitigation

If useful, I can provide a smaller patch proposal focused specifically on createTranscriptUpdateBroadcastHandler(...) as a stopgap mitigation.

Code Example

Observed duplicate content pattern:

Sender (untrusted metadata):

---

[Mon 2026-04-27 17:31 GMT+3] 1
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

Control UI / webchat can duplicate a single user message into two visible user turns:

  • one normal local/plain user message
  • one echoed user message whose content begins with Sender (untrusted metadata): and whose sender label resolves to openclaw-control-ui

This appears to be a regression after 2026.4.24 / present in 2026.4.24+ builds.

This is not just double ingress from the browser. The current code path can emit two different user-message representations for the same logical turn.

Steps to reproduce

  1. Update OpenClaw to a recent 2026.4.24+ build.
  2. Open Control UI webchat.
  3. Send a simple message such as 1.
  4. Observe that the same user turn may appear twice.
  5. One duplicate contains/derives from inbound metadata and may show sender label openclaw-control-ui.

Expected behavior

A single webchat user input should produce exactly one visible user turn in Control UI.

Inbound metadata such as Sender (untrusted metadata): must never be shown in user-visible chat history.

Actual behavior

The same logical webchat user turn can be surfaced twice:

  1. a plain user message
  2. a second user message carrying inbound metadata / sender label openclaw-control-ui

OpenClaw version

Observed after update to 2026.4.24; still reproducible in current npm build (2026.4.24+ family)

Operating system

Linux (gateway host), reproduced from browser-based Control UI

Install method

npm / global install

Model

Not model-specific

Provider / routing chain

Browser Control UI (webchat) -> OpenClaw gateway -> main agent session

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Observed duplicate content pattern:

Sender (untrusted metadata):
```json
{
  "label": "openclaw-control-ui",
  "id": "openclaw-control-ui"
}

[Mon 2026-04-27 17:31 GMT+3] 1


### Root cause analysis

The current runtime appears to have **two separate user-turn paths** for the same `webchat` input:

#### 1) Early webchat transcript update path

`/root/.nvm/versions/node/v22.22.2/lib/node_modules/openclaw/dist/chat-DznnoAn8.js`

- `emitUserTranscriptUpdate()` at `2369-2394`
- calls `emitSessionTranscriptUpdate({ message: buildChatSendTranscriptMessage(...) })`
- `buildChatSendTranscriptMessage(...)` at `1263-1270` produces a plain:
  - `role: "user"`
  - `content: params.message`

#### 2) Main reply/transcript path with inbound metadata

`/root/.nvm/versions/node/v22.22.2/lib/node_modules/openclaw/dist/get-reply-CSQ5BMwG.js`

- `buildInboundUserContextPrefix(...)` at `1820`
- inbound user context is assembled into prompt/transcript body around `2231-2242`
- `transcriptCommandBody` is passed onward at `2455-2456` and `2533-2534`

Then runner path forwards transcript prompt:

`/root/.nvm/versions/node/v22.22.2/lib/node_modules/openclaw/dist/agent-runner.runtime-CbAg9IpO.js`

- CLI path: `732`
- embedded path: `831`
- run dispatch: `3070`

#### 3) Transcript update broadcast does not sanitize the visible message

`/root/.nvm/versions/node/v22.22.2/lib/node_modules/openclaw/dist/server.impl-CtLS1ywt.js`

- `createTranscriptUpdateBroadcastHandler(...)` at `9229-9253`
- broadcasts `update.message` via `session.message`
- does **not** call `stripInboundMetadata(...)` / `stripEnvelopeFromMessage(...)`

#### 4) There is already an explicit contract that this metadata must never be displayed

`/root/.nvm/versions/node/v22.22.2/lib/node_modules/openclaw/dist/strip-inbound-meta-DaDVfj8b.js`

Header comment says OpenClaw-injected inbound metadata blocks are AI-facing only and:

> must never surface in user-visible chat history

The sentinel list includes:

- `Conversation info (untrusted metadata):`
- `Sender (untrusted metadata):`

### Interpretation

This strongly suggests a regression where `webchat` now exposes both:

1. the early plain user transcript update
2. a second transcript/broadcast path carrying inbound metadata

So this is not just an external duplicate submit. It is an internal duplication / consumer-sanitization failure.

### Proposed fix

#### Minimal safe mitigation

Sanitize transcript-broadcast user messages before they are sent to Control UI in:

- `createTranscriptUpdateBroadcastHandler(...)`

using the same stripping path already intended for display surfaces, e.g. `stripInboundMetadata(...)` / `stripEnvelopeFromMessage(...)`.

#### Proper fix

Ensure `webchat` produces only **one canonical user-turn representation** per input.

Either:

1. suppress the early `emitUserTranscriptUpdate()` path for normal `webchat` user turns, or
2. suppress the later duplicate transcript-visible user entry when it represents the same logical turn, or
3. add stable dedupe/idempotency across transcript update broadcast for the same webchat user turn.

### Related issues

- #72671 — earlier report with similar symptom, but closed
- #72227 — optimistic `You` vs `openclaw-control-ui` duplicate, closed
- #69208 — umbrella: duplicate transcript / replay / context assembly across channels
- #71992 — related Control UI duplicate regression on assistant side

### Impact and severity

User-visible duplicate messages in Control UI, plus visible leakage of internal inbound metadata.

Also likely increases confusion during transcript/history/debugging and may indicate broader duplicate persistence / duplicate broadcast behavior.

### Additional information

If useful, I can provide a smaller patch proposal focused specifically on `createTranscriptUpdateBroadcastHandler(...)` as a stopgap mitigation.

extent analysis

TL;DR

The most likely fix is to sanitize transcript-broadcast user messages in createTranscriptUpdateBroadcastHandler() using stripInboundMetadata() or stripEnvelopeFromMessage() to prevent duplicate messages and metadata leakage.

Guidance

  • Review the createTranscriptUpdateBroadcastHandler() function to ensure it properly sanitizes user messages before broadcasting them to Control UI.
  • Consider suppressing the early emitUserTranscriptUpdate() path for normal webchat user turns to prevent duplicate messages.
  • Investigate adding stable dedupe/idempotency across transcript update broadcast for the same webchat user turn to prevent duplicates.
  • Verify that the stripInboundMetadata() and stripEnvelopeFromMessage() functions are correctly implemented and used to remove internal inbound metadata.

Example

// Example of sanitizing user messages in createTranscriptUpdateBroadcastHandler()
const sanitizedMessage = stripInboundMetadata(update.message);
session.message(sanitizedMessage);

Notes

The provided information suggests a regression in the webchat functionality, and the proposed fix focuses on sanitizing transcript-broadcast user messages. However, a more comprehensive solution may require ensuring that webchat produces only one canonical user-turn representation per input.

Recommendation

Apply the proposed minimal safe mitigation by sanitizing transcript-broadcast user messages in createTranscriptUpdateBroadcastHandler() to prevent duplicate messages and metadata leakage. This should be a temporary workaround until a more comprehensive solution can be implemented.

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 single webchat user input should produce exactly one visible user turn in Control UI.

Inbound metadata such as Sender (untrusted metadata): must never be shown in user-visible chat history.

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 - 💡(How to fix) Fix [Bug]: Control UI / webchat duplicates user message and leaks `Sender (untrusted metadata)` as `openclaw-control-ui` [2 comments, 2 participants]