openclaw - ✅(Solved) Fix Strip <relevant-memories> blocks from outbound channel messages (Telegram, Discord, etc.) [1 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#74364Fetched 2026-04-30 06:24:55
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
2
Timeline (top)
commented ×1cross-referenced ×1mentioned ×1subscribed ×1

When the memory plugin (openclaw-mem0 or memory-lancedb) injects <relevant-memories> context via the prependContext hook, and the LLM echoes/reflects this block in its response, the raw <relevant-memories>...</relevant-memories> markup is delivered verbatim to messaging channels like Telegram. This leaks internal memory context to the user as visible plaintext.

The Web UI already has a fix for this (#29851) that strips <relevant-memories> scaffolding from rendered assistant messages. However, the same sanitization is not applied to outbound messages sent through messaging channels (Telegram, Discord, Slack, iMessage, etc.).

Root Cause

When the memory plugin (openclaw-mem0 or memory-lancedb) injects <relevant-memories> context via the prependContext hook, and the LLM echoes/reflects this block in its response, the raw <relevant-memories>...</relevant-memories> markup is delivered verbatim to messaging channels like Telegram. This leaks internal memory context to the user as visible plaintext.

The Web UI already has a fix for this (#29851) that strips <relevant-memories> scaffolding from rendered assistant messages. However, the same sanitization is not applied to outbound messages sent through messaging channels (Telegram, Discord, Slack, iMessage, etc.).

Fix Action

Fixed

PR fix notes

PR #74436: fix(channels): strip <relevant-memories> from outbound assistant text

Description (problem / solution / changelog)

Summary

Fixes #74364. When the memory plugin injects <relevant-memories> context via prependContext and the LLM echoes the block, the raw markup is delivered verbatim to messaging channels (Telegram, Discord, etc.).

The shared stripRelevantMemoriesTags (src/shared/text/assistant-visible-text.ts:517) already strips these blocks with code-fence-aware preservation, but sanitizeUserFacingText (src/agents/pi-embedded-helpers/sanitize-user-facing-text.ts) — the canonical outbound text sanitizer used by bash-tools.exec-approval-followup.ts, auto-reply/reply/normalize-reply.ts, and auto-reply/reply/agent-runner-execution.ts — doesn't call into it.

Change

  • Export stripRelevantMemoriesTags.
  • Wrap the existing strip chain in sanitizeUserFacingText so it lands on the same boundary that already strips inbound metadata, internal runtime context, and final tags.
  • Three regression tests in pi-embedded-helpers.sanitizeuserfacingtext.test.ts: reflected block stripped, code-fence preservation, interleaved-with-prose strip.

Testing

pnpm test src/agents/pi-embedded-helpers.sanitizeuserfacingtext.test.ts
# 89/89 passing
pnpm exec oxfmt --check --threads=1 <touched files>
# green

Out of scope

  • This fix does not cover the partial-preview/streaming paths (pi-embedded-subscribe.ts text_end, pi-embedded-subscribe.handlers.messages.ts partial preview), which use a different sanitizer and may require a separate fix if the leak is confirmed there.
  • Provider-side fix to prevent the LLM from echoing memory tags (out of scope per existing pattern of sanitizing at the delivery boundary).

Suggested release note

Outbound channel messages no longer leak <relevant-memories> scaffolding when the memory plugin's context is reflected back by the LLM.

Changed files

  • src/agents/pi-embedded-helpers.sanitizeuserfacingtext.test.ts (modified, +46/-0)
  • src/agents/pi-embedded-helpers/sanitize-user-facing-text.ts (modified, +4/-1)
  • src/shared/text/assistant-visible-text.ts (modified, +1/-1)

Code Example

<relevant-memories>
The following are stored memories for user "kevin". Use them to personalize your response:
- Kevin prefers operator mode with verification discipline
- VEDA uses Opus 4.6 as main model
...
</relevant-memories>

[Actual response follows]

---

// agent-harness-runtime-CpgGKKoD.js:49
prompt: joinPresentTextSegments([promptBuildResult?.prependContext, legacyResult?.prependContext, params.prompt])

// prepare.runtime-O4dLDhbV.js:765
if (hookResult.prependContext) preparedPrompt = `${hookResult.prependContext}\n\n${preparedPrompt}`;

---

text = text.replace(/<relevant-memories>[\s\S]*?<\/relevant-memories>\s*/g, "").trim();
RAW_BUFFERClick to expand / collapse

Strip <relevant-memories> blocks from outbound channel messages (Telegram, Discord, etc.)

Description

When the memory plugin (openclaw-mem0 or memory-lancedb) injects <relevant-memories> context via the prependContext hook, and the LLM echoes/reflects this block in its response, the raw <relevant-memories>...</relevant-memories> markup is delivered verbatim to messaging channels like Telegram. This leaks internal memory context to the user as visible plaintext.

The Web UI already has a fix for this (#29851) that strips <relevant-memories> scaffolding from rendered assistant messages. However, the same sanitization is not applied to outbound messages sent through messaging channels (Telegram, Discord, Slack, iMessage, etc.).

Steps to Reproduce

  1. Configure openclaw-mem0 (or any memory plugin that uses prependContext) with autoRecall enabled
  2. Connect a Telegram channel
  3. Send messages that trigger memory recall (the plugin injects <relevant-memories> blocks into the user prompt)
  4. Wait for the LLM to reflect/echo the <relevant-memories> block in its response (happens intermittently, more common with longer context or subagent completions)
  5. Observe the raw <relevant-memories> block rendered as visible text in Telegram

Expected Behavior

The <relevant-memories> block should be stripped from assistant responses before delivery to any channel, just as it is in the Web UI. The user should never see internal memory scaffolding.

Actual Behavior

The <relevant-memories>...</relevant-memories> block (including the preamble text like "The following are stored memories for user...") is rendered as visible plaintext in Telegram messages.

Example of what Kevin sees in Telegram:

<relevant-memories>
The following are stored memories for user "kevin". Use them to personalize your response:
- Kevin prefers operator mode with verification discipline
- VEDA uses Opus 4.6 as main model
...
</relevant-memories>

[Actual response follows]

Environment

  • OpenClaw version: 2026.4.26
  • Memory plugin: @mem0/openclaw-mem0 1.0.4
  • Channels affected: Telegram (long-polling), likely all messaging channels
  • Web UI: Not affected (already has fix from #29851)

Analysis

How prependContext works

The memory plugin returns <relevant-memories> blocks via the beforeAgentStart / before_prompt_build hook's prependContext field. The gateway prepends this directly to the user message text:

// agent-harness-runtime-CpgGKKoD.js:49
prompt: joinPresentTextSegments([promptBuildResult?.prependContext, legacyResult?.prependContext, params.prompt])

// prepare.runtime-O4dLDhbV.js:765
if (hookResult.prependContext) preparedPrompt = `${hookResult.prependContext}\n\n${preparedPrompt}`;

Where sanitization happens (and doesn't)

  • Web UI: Strips <relevant-memories> from rendered chat messages (#29851)
  • Memory capture pipeline: Strips <relevant-memories> before sending to Mem0 extraction (mem0 plugin line ~3988)
  • iMessage inbound: detectReflectedContent() catches relevant-memories-tag pattern and drops reflected inbound messages
  • Channel outbound: No stripping. The parseChunksplitMediaFromOutputemitBlockReply pipeline has no filter for <relevant-memories> tags

Related mechanisms that DON'T cover this

  • stripInternalRuntimeContext handles <<<BEGIN_OPENCLAW_INTERNAL_CONTEXT>>> blocks but not <relevant-memories>
  • detectReflectedContent in monitor-ChxbhW0l.js detects the pattern but is only used for iMessage inbound filtering

Suggested Fix

Add <relevant-memories> stripping to the channel outbound text processing pipeline, before text reaches emitBlockReply. The regex is already proven in the mem0 capture pipeline:

text = text.replace(/<relevant-memories>[\s\S]*?<\/relevant-memories>\s*/g, "").trim();

Ideal locations:

  1. In parseChunk (selection-D9uTvvsw.js) after splitMediaFromOutput — affects all channels
  2. Or extend stripInternalRuntimeContext to also handle <relevant-memories> blocks
  3. Or add a general plugin-context sanitizer for outbound messages

This should preserve <relevant-memories> inside code fences (matching the Web UI behavior from #29851).

extent analysis

TL;DR

Add a stripping mechanism for <relevant-memories> blocks in the channel outbound text processing pipeline to prevent internal memory context from being sent to users.

Guidance

  • Identify the optimal location for the stripping mechanism, such as in parseChunk after splitMediaFromOutput, to affect all channels.
  • Use the existing regex pattern /\<relevant-memories\>[\s\S]*?\<\/relevant-memories\>\s*/g to match and remove <relevant-memories> blocks.
  • Consider extending stripInternalRuntimeContext to handle <relevant-memories> blocks for a more comprehensive solution.
  • Verify the fix by testing with various messaging channels and ensuring that <relevant-memories> blocks are no longer visible in outbound messages.

Example

text = text.replace(/<relevant-memories>[\s\S]*?<\/relevant-memories>\s*/g, "").trim();

This code snippet demonstrates the proposed stripping mechanism using the provided regex pattern.

Notes

The suggested fix assumes that the regex pattern effectively matches and removes <relevant-memories> blocks without affecting other parts of the message. Additional testing may be necessary to ensure the solution works as expected across different channels and message formats.

Recommendation

Apply the workaround by adding the stripping mechanism to the channel outbound text processing pipeline, as it directly addresses the issue and prevents internal memory context from being leaked to users.

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…

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 Strip <relevant-memories> blocks from outbound channel messages (Telegram, Discord, etc.) [1 pull requests, 1 comments, 2 participants]