openclaw - 💡(How to fix) Fix [Bug]: delivery-mirror assistant messages pollute LLM context causing infinite loop (distinct from #71912, #74034) [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#74973Fetched 2026-05-01 05:39:24
View on GitHub
Comments
1
Participants
2
Timeline
2
Reactions
2
Timeline (top)
closed ×1commented ×1

When delivery-mirror appends assistant messages to the session transcript, buildSessionContext() returns them to the LLM as normal conversation context. The LLM misinterprets these delivery-mirror messages as its own previous output and responds by calling the message tool again, creating an infinite loop that rapidly consumes the context window.

In our case, the Xiaotong (晓桐) agent reached 131K/131K tokens stuck in a loop repeatedly sending the same PDF, requiring a Gateway restart.

Root Cause

Traced the code path:

  1. deliver-CClC7J0O.js:1050-1051appendAssistantMessageToSessionTranscript() writes delivery-mirror entries with model: "delivery-mirror"
  2. session-manager.jsbuildSessionContext() returns ALL messages (line 108+) including these delivery-mirror entries
  3. pi-embedded-runner-CefZK1Pt.js:5629sanitizeSessionHistory() is called but the filtering doesn't cover all code paths (e.g., the second prompt cycle bypasses full sanitization)
  4. pi-embedded-runner-CefZK1Pt.js:1045isTranscriptOnlyOpenClawAssistantMessage() exists but is only used for event emission, not context filtering

Fix Action

Fix / Workaround

How this differs from previous issues

  • #71912: Root cause was antml: thinking tag regex leak in streaming pipeline — fixed in #72032
  • #74034: Root cause was heartbeat + auth fallback cascade generating repeated messages
  • This issue: Root cause is delivery-mirror messages being returned by buildSessionContext() as normal LLM context — a separate code path that was not fixed by the above

Code Example

const filteredPrior = prior.filter((msg) =>
  !(msg?.role === "assistant" && msg?.provider === "openclaw" && msg?.model === "delivery-mirror")
);
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (infinite loop, context window exhaustion)

Beta release blocker

No

Summary

When delivery-mirror appends assistant messages to the session transcript, buildSessionContext() returns them to the LLM as normal conversation context. The LLM misinterprets these delivery-mirror messages as its own previous output and responds by calling the message tool again, creating an infinite loop that rapidly consumes the context window.

In our case, the Xiaotong (晓桐) agent reached 131K/131K tokens stuck in a loop repeatedly sending the same PDF, requiring a Gateway restart.

Steps to reproduce

  1. Configure any agent with delivery-mirror enabled
  2. Use the message tool with action=send and a file (e.g., filePath: xxx.pdf)
  3. The delivery system appends an assistant message with model: "delivery-mirror", provider: "openclaw" to the session transcript
  4. On the next LLM turn, buildSessionContext() includes this delivery-mirror message in the context
  5. The LLM sees it as normal conversation context and may call message again
  6. Loop continues until context window is exhausted

Expected behavior

delivery-mirror messages should be invisible to the LLM context. They are internal delivery bookkeeping and should not be fed back into the conversation.

Actual behavior

buildSessionContext() in session-manager.js returns ALL messages including delivery-mirror entries. The existing isTranscriptOnlyOpenClawAssistantMessage() filter in pi-embedded-runner-CefZK1Pt.js:1045 correctly identifies these messages but is only used in event handlers (handleMessageEnd, etc.), NOT in the main LLM context assembly pipeline.

Root Cause Analysis

Traced the code path:

  1. deliver-CClC7J0O.js:1050-1051appendAssistantMessageToSessionTranscript() writes delivery-mirror entries with model: "delivery-mirror"
  2. session-manager.jsbuildSessionContext() returns ALL messages (line 108+) including these delivery-mirror entries
  3. pi-embedded-runner-CefZK1Pt.js:5629sanitizeSessionHistory() is called but the filtering doesn't cover all code paths (e.g., the second prompt cycle bypasses full sanitization)
  4. pi-embedded-runner-CefZK1Pt.js:1045isTranscriptOnlyOpenClawAssistantMessage() exists but is only used for event emission, not context filtering

How this differs from previous issues

  • #71912: Root cause was antml: thinking tag regex leak in streaming pipeline — fixed in #72032
  • #74034: Root cause was heartbeat + auth fallback cascade generating repeated messages
  • This issue: Root cause is delivery-mirror messages being returned by buildSessionContext() as normal LLM context — a separate code path that was not fixed by the above

Temporary Fix Applied

Added forced filtering after sanitizeSessionHistory() in pi-embedded-runner-CefZK1Pt.js:

const filteredPrior = prior.filter((msg) =>
  !(msg?.role === "assistant" && msg?.provider === "openclaw" && msg?.model === "delivery-mirror")
);

This works and stops the loop, confirming the root cause.

Suggested Permanent Fix

  1. Filter model: "delivery-mirror" messages at the source — either in buildSessionContext() or ensure sanitizeSessionHistory() catches ALL paths where messages are fed to the LLM
  2. Alternatively, use a non-assistant role for delivery-mirror entries so they are never treated as LLM output

Environment

  • OpenClaw version: 2026.4.12
  • Node.js: v22.22.2
  • Platform: WSL2 (Linux 6.6.87.2-microsoft-standard-WSL2, x64)
  • Model: dashscope/qwen3.6-plus
  • Plugin: @tencent-connect/openclaw-qqbot v1.7.0

Impact

  • Session token exhaustion (131K tokens in one loop)
  • Gateway restart required to clear affected sessions
  • Affects any agent using message(action=send) with file delivery

extent analysis

TL;DR

Filtering out delivery-mirror messages in buildSessionContext() or ensuring sanitizeSessionHistory() covers all code paths can prevent the infinite loop.

Guidance

  • Identify and filter out delivery-mirror messages at the source to prevent them from being treated as normal LLM context.
  • Consider using a non-assistant role for delivery-mirror entries to prevent the LLM from interpreting them as its own output.
  • Review the sanitizeSessionHistory() function to ensure it covers all code paths where messages are fed to the LLM.
  • Apply the temporary fix as a permanent solution by integrating the filtering logic into buildSessionContext() or sanitizeSessionHistory().

Example

const filteredMessages = messages.filter((msg) =>
  !(msg?.role === "assistant" && msg?.provider === "openclaw" && msg?.model === "delivery-mirror")
);

Notes

The suggested permanent fix requires careful review of the code to ensure that all paths where messages are fed to the LLM are covered. The temporary fix has been confirmed to work, but a more robust solution is needed to prevent similar issues in the future.

Recommendation

Apply the suggested permanent fix by filtering out delivery-mirror messages at the source, as it addresses the root cause of the issue and prevents the infinite loop.

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

delivery-mirror messages should be invisible to the LLM context. They are internal delivery bookkeeping and should not be fed back into the conversation.

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]: delivery-mirror assistant messages pollute LLM context causing infinite loop (distinct from #71912, #74034) [1 comments, 2 participants]