openclaw - ✅(Solved) Fix Outbound message rendering: internal metadata label leaking into chat replies [3 pull requests, 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#74745Fetched 2026-05-01 05:41:50
View on GitHub
Comments
1
Participants
2
Timeline
12
Reactions
2
Author
Timeline (top)
referenced ×7cross-referenced ×3closed ×1commented ×1

Fix Action

Fixed

PR fix notes

PR #74753: fix(agents): strip replay metadata placeholder from user-facing text

Description (problem / solution / changelog)

Summary

  • Problem: Internal replay placeholder [assistant copied inbound metadata omitted] is leaking into outbound Telegram messages after 2026.4.27
  • Why it matters: Users see internal scaffolding text instead of (or in addition to) the actual assistant response
  • What changed: Extended the existing replay placeholder stripping to also filter this metadata placeholder
  • What did NOT change: Inline mentions of the placeholder (e.g. user asking "what does this mean?") are preserved

Regression: Introduced in ee8f41f56e (2026-04-26) which added the placeholder in replay-history.ts but did not add corresponding filtering in sanitize-user-facing-text.ts.

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 #74745
  • Related to ee8f41f56e (commit that introduced the placeholder)
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: normalizeAssistantReplayContent in replay-history.ts synthesizes [assistant copied inbound metadata omitted] when stripped assistant replay text becomes empty, but sanitizeUserFacingText only stripped [tool calls omitted] placeholder lines
  • Missing detection / guardrail: The new placeholder was not added to the outbound sanitizer
  • Contributing context: If LLM echoes the replay history or certain edge cases occur, the placeholder leaks to user-facing delivery

Regression Test Plan (if applicable)

  • Coverage level:
    • Unit test
  • Target test file: src/agents/pi-embedded-helpers.sanitizeuserfacingtext.test.ts
  • Scenario the test should lock in: Standalone [assistant copied inbound metadata omitted] lines are stripped, inline mentions are preserved
  • Why this is the smallest reliable guardrail: Tests the central sanitizer that all outbound paths use
  • Existing test that already covers this: None for this specific placeholder

User-visible / Behavior Changes

  • Internal placeholder text no longer appears in delivered messages
  • Users receive actual assistant responses instead of scaffolding text

Diagram (if applicable)

Before:
[replay-history synthesizes placeholder] -> [sanitizer misses it] -> [user sees "[assistant copied inbound metadata omitted]"]

After:
[replay-history synthesizes placeholder] -> [sanitizer strips it] -> [user sees actual response or empty string]

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

Repro + Verification

Environment

  • OS: macOS Darwin 25.3.0
  • Runtime/container: Node.js v22.22.0
  • Model/provider: Any
  • Integration/channel: Telegram (reported), affects all channels

Steps

  1. Trigger a session where replay-history synthesizes the metadata placeholder
  2. Observe outbound message delivery

Expected

  • Placeholder is stripped; user sees actual response

Actual

  • Works as expected after fix

Evidence

  • Failing test/log before + passing after
pnpm test src/agents/pi-embedded-helpers.sanitizeuserfacingtext.test.ts
# All tests pass including new regression tests

New tests verify:

expect(sanitizeUserFacingText("[assistant copied inbound metadata omitted]")).toBe("");
expect(sanitizeUserFacingText("Hello\n\n[assistant copied inbound metadata omitted]\nWorld\n")).toBe("Hello\n\nWorld\n");
// Inline mentions preserved
expect(sanitizeUserFacingText("What does [assistant copied inbound metadata omitted] mean?"))
  .toBe("What does [assistant copied inbound metadata omitted] mean?");

Human Verification (required)

  • Verified scenarios: Unit tests pass, code review, regex logic inspection
  • Edge cases checked: Standalone line, multiple lines, inline mention preservation
  • What you did NOT verify: E2E session replay (unit tests cover the sanitizer path)

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

Risks and Mitigations

  • Risk: Regex could over-match and strip legitimate user content
    • Mitigation: Only matches exact standalone placeholder lines (with optional whitespace); inline mentions are preserved by design and tested

Changed files

  • src/agents/pi-embedded-helpers.sanitizeuserfacingtext.test.ts (modified, +16/-0)
  • src/agents/pi-embedded-helpers/sanitize-user-facing-text.ts (modified, +5/-4)
  • src/auto-reply/reply/reply-utils.test.ts (modified, +16/-0)

PR #74785: fix(pi-embedded): strip [assistant copied inbound metadata omitted] placeholder from delivery

Description (problem / solution / changelog)

Problem

The internal replay placeholder [assistant copied inbound metadata omitted] is leaking into outbound Telegram (and other channel) messages after the 2026.4.27 update, appearing as the entire message body instead of the actual assistant reply.

Fixes #74745.

Root cause

sanitize-user-facing-text.ts already strips [tool calls omitted] from user-facing output (landed in d30b8dccfd, fixing #74573). The same sentinel pattern OMITTED_INBOUND_METADATA_TEXT = "[assistant copied inbound metadata omitted]" synthesized by normalizeAssistantReplayContent in replay-history.ts was not covered by the stripping regex.

Solution

Extend TOOL_CALLS_OMITTED_PLACEHOLDER_LINE_RE to cover both placeholder variants using an alternation group:

-const TOOL_CALLS_OMITTED_PLACEHOLDER_LINE_RE = /^[ \t]*\[tool calls omitted\][ \t]*$/i;
+const TOOL_CALLS_OMITTED_PLACEHOLDER_LINE_RE =
+  /^[ \t]*\[(?:tool calls omitted|assistant copied inbound metadata omitted)\][ \t]*$/i;

Same standalone-line logic applies: only strip when the placeholder is the entire line content, so ordinary user discussion of the placeholder text is preserved.

Tests

Added 4 test assertions mirroring the existing [tool calls omitted] coverage — standalone strip, whitespace strip, mid-text strip, and inline-mention preservation. All 90/90 tests pass.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/pi-embedded-helpers.sanitizeuserfacingtext.test.ts (modified, +19/-0)
  • src/agents/pi-embedded-helpers/sanitize-user-facing-text.ts (modified, +4/-3)

PR #74828: fix: regression/data-loss edge case in the new metadata-only assistant drop path

Description (problem / solution / changelog)

Summary

Found one regression/data-loss edge case in the new metadata-only assistant drop path.

What ClawSweeper Is Fixing

  • Medium: Dropping metadata-only assistant turns can erase adjacent string user prompts during Anthropic replay validation (regression)
    • File: src/agents/pi-embedded-runner/replay-history.ts:321
    • Evidence: The new path returns null when an assistant block array becomes empty after stripInboundMetadata, so a history like user("First") -> assistant(metadata-only) -> user("Second") becomes two adjacent user turns. The next runtime boundary calls sanitizeSessionHistory and then validateReplayTurns in src/agents/pi-embedded-runner/run/attempt.ts:1918 and src/agents/pi-embedded-runner/run/attempt.ts:1933. For Anthropic replay, mergeConsecutiveUserTurns only preserves array content and drops string content via Array.isArray(...) ? ... : [] in src/agents/pi-embedded-helpers/turns.ts:352. A focused probe reproduced this exact loss:
    • Impact: Common persisted user messages use string content. After this commit, a metadata-only assistant replay turn between two string user turns can make Anthropic-class replay send an empty user message instead of the actual prior/latest prompts, causing bad replies or provider rejection. The new regression test covers only array-shaped user content at src/agents/pi-embedded-runner.sanitize-session-history.test.ts:1143, so it misses this production-shaped case.
    • Suggested fix: Preserve string user content when merging consecutive user turns, e.g. normalize strings into { type: "text", text } blocks before concatenation, and add a regression test using string user messages around the dropped metadata-only assistant turn.
    • Confidence: high

Expected Repair Surface

  • src/agents/pi-embedded-runner/replay-history.ts
  • src/agents/pi-embedded-runner/replay-history.test.ts
  • src/agents/pi-embedded-runner.sanitize-session-history.test.ts

Source And Review Context

Expected validation

  • pnpm check:changed

ClawSweeper already ran:

  • pnpm docs:list
  • pnpm install
  • OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test src/agents/pi-embedded-runner/replay-history.test.ts src/agents/pi-embedded-runner.sanitize-session-history.test.ts passed: 67 tests
  • node --import tsx -e ...normalizeAssistantReplayContent + validateAnthropicTurns... reproduced the string-user content loss
  • git diff --check bb449092626193dae04e91f9124caaf821caec1f d80a8eb3adb6b26fb345fdc7b658dbd39f085e35 passed
  • One earlier test attempt failed because I accidentally passed Jest’s --runInBand; it was rerun successfully with the repo’s Vitest-compatible worker setting.

Known review limits:

  • Did not run a live Telegram or Anthropic provider send; the finding is based on source trace plus a focused local replay-normalization probe.

ClawSweeper Guardrails

  • Re-check the finding against latest main before changing code.
  • Keep the patch to the narrowest behavior change and matching regression coverage.
  • Do not merge automatically; this PR stays for maintainer review.

ClawSweeper 🐠 replacement reef notes:

  • Cluster: clawsweeper-commit-openclaw-openclaw-d80a8eb3adb6
  • Source PRs: none
  • Credit: Detected by ClawSweeper commit review for d80a8eb3adb6b26fb345fdc7b658dbd39f085e35.; Original commit author: Peter Steinberger.
  • Validation: pnpm check:changed

fish notes: model gpt-5.5, reasoning medium; reviewed against 99a6a311a9aa.

Changed files

  • src/agents/pi-embedded-helpers.validate-turns.test.ts (modified, +20/-0)
  • src/agents/pi-embedded-helpers/turns.ts (modified, +16/-2)
  • src/agents/pi-embedded-runner.sanitize-session-history.test.ts (modified, +2/-10)
RAW_BUFFERClick to expand / collapse

Bug Description

Internal session metadata labels are leaking into outbound Telegram messages after the 2026.4.27 update.

What's happening

Two issues observed in the same session:

  1. The literal text [assistant copied inbound metadata omitted] is appearing as part of the delivered Telegram message text — it should be stripped before delivery.

  2. When this label appears, it seems to eat/replace the actual assistant reply — so the user receives the label text instead of the intended response, not appended to it.

Steps to reproduce

  • Running OpenClaw 2026.4.27 (cbc2ba0) on Telegram channel
  • Session receives a message that triggered duplicate-message handling or internal metadata annotation
  • Next assistant reply delivers the internal label string to the user in Telegram instead of (or in addition to) the actual response

Expected behavior

Internal metadata labels are never visible to users in any channel. They are stripped before delivery.

Actual behavior

[assistant copied inbound metadata omitted] appears as the delivered message content in Telegram.

Environment

  • OpenClaw: 2026.4.27 (cbc2ba0)
  • Channel: Telegram
  • OS: macOS Darwin 25.3.0 (arm64)
  • Node: v22.22.0

extent analysis

TL;DR

The issue can be fixed by modifying the message processing pipeline to strip internal session metadata labels before delivering messages to the Telegram channel.

Guidance

  • Review the message processing code to identify where the internal metadata label is being appended or not stripped, and modify it to remove the label before delivery.
  • Verify that the cbc2ba0 commit in OpenClaw 2026.4.27 introduced the issue by checking the commit history and comparing the behavior with previous versions.
  • Check the duplicate-message handling and internal metadata annotation logic to ensure it's not interfering with the message processing pipeline.
  • Test the fix by reproducing the issue and verifying that the internal metadata label is no longer visible in the delivered Telegram message.

Example

No code snippet is provided as the issue does not contain sufficient information about the codebase.

Notes

The issue seems to be specific to the OpenClaw 2026.4.27 update and the Telegram channel, so the fix may need to be targeted to this specific version and channel.

Recommendation

Apply a workaround to strip the internal metadata label from the message text before delivery, as the root cause of the issue is likely a bug in the message processing pipeline.

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

Internal metadata labels are never visible to users in any channel. They are stripped before delivery.

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 Outbound message rendering: internal metadata label leaking into chat replies [3 pull requests, 1 comments, 2 participants]