openclaw - 💡(How to fix) Fix delivery-mirror: writes role:assistant into parent session without paired user message, violating Anthropic alternation [1 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#70869Fetched 2026-04-24 10:38:33
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×1

Error Message

When a cron job or subagent session uses the message tool to send outbound messages (e.g., Telegram alerts), OpenClaw writes the sent text back into the parent/originating session transcript as role: assistant with no preceding role: user message. This violates Anthropic's message alternation requirement and eventually causes API rejection with a prefill error.

Root Cause

Root cause (traced to source): message-action-runner-DpHptjwv.js line ~1102:

mirror: outboundRoute && !dryRun ? {
  sessionKey: outboundRoute.sessionKey,
  agentId,
  text: message,
  mediaUrls: mirrorMediaUrls
} : void 0,

This unconditionally creates a mirror object when outboundRoute resolves to the parent session. The deliverOutboundPayloads function then calls appendAssistantMessageToSessionTranscript with this data, writing an assistant message with model: "delivery-mirror" into the parent session — regardless of whether a user message precedes it.

Code Example

mirror: outboundRoute && !dryRun ? {
  sessionKey: outboundRoute.sessionKey,
  agentId,
  text: message,
  mediaUrls: mirrorMediaUrls
} : void 0,
RAW_BUFFERClick to expand / collapse

Bug Report

Severity: High — causes silent session corruption and API rejection

Summary: When a cron job or subagent session uses the message tool to send outbound messages (e.g., Telegram alerts), OpenClaw writes the sent text back into the parent/originating session transcript as role: assistant with no preceding role: user message. This violates Anthropic's message alternation requirement and eventually causes API rejection with a prefill error.

Root cause (traced to source): message-action-runner-DpHptjwv.js line ~1102:

mirror: outboundRoute && !dryRun ? {
  sessionKey: outboundRoute.sessionKey,
  agentId,
  text: message,
  mediaUrls: mirrorMediaUrls
} : void 0,

This unconditionally creates a mirror object when outboundRoute resolves to the parent session. The deliverOutboundPayloads function then calls appendAssistantMessageToSessionTranscript with this data, writing an assistant message with model: "delivery-mirror" into the parent session — regardless of whether a user message precedes it.

Evidence:

  • SN62 cron job running at 23:05:15 UTC on 2026-04-23 wrote its Telegram alert text into session f8ee6b28 as a consecutive assistant message
  • This created a role: assistant → role: assistant sequence in the session, which Anthropic's API eventually rejected
  • Confirmed by inspecting LCM conversation data

Impact:

  • Every cron job or isolated session that sends a Telegram/channel message creates a mirror entry in the parent session
  • The mirror has no paired user message, so every occurrence creates a potential corruption point
  • LCM accumulates these permanently (see related bug), making the session progressively more unstable

No config toggle exists: The behavior is hardcoded. There is no session.disableDeliveryMirror or equivalent setting.

Request:

  1. Add a config toggle (e.g., session.deliveryMirror: false) to disable transcript mirroring for outbound channel messages
  2. Or, at minimum, skip the mirror write when it would create a consecutive assistant message (violate alternation)
  3. Consider skipping the mirror write entirely when the source is a cron/isolated session \u2014 the message already delivered to the channel; the session echo adds no user-facing value

extent analysis

TL;DR

To fix the issue, add a conditional check to prevent writing a mirror message as an assistant message when it would create a consecutive assistant message without a preceding user message.

Guidance

  • Identify the deliverOutboundPayloads function and modify it to check if the last message in the session transcript is an assistant message before calling appendAssistantMessageToSessionTranscript.
  • Consider adding a config toggle, such as session.deliveryMirror, to allow disabling transcript mirroring for outbound channel messages.
  • When the source is a cron or isolated session, evaluate whether the mirror write provides any user-facing value and consider skipping it to prevent session corruption.
  • Review the message-action-runner-DpHptjwv.js file, specifically line ~1102, to ensure the mirror object creation is conditional and does not unconditionally write to the parent session.

Example

if (lastMessageInTranscript.role !== 'assistant' || !outboundRoute) {
  // Call appendAssistantMessageToSessionTranscript
} else {
  // Skip writing the mirror message
}

Notes

The provided code snippet assumes the existence of a lastMessageInTranscript variable, which may need to be implemented or replaced with an equivalent check.

Recommendation

Apply a workaround by modifying the deliverOutboundPayloads function to conditionally skip writing the mirror message when it would create a consecutive assistant message, as this directly addresses the root cause of the issue.

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 - 💡(How to fix) Fix delivery-mirror: writes role:assistant into parent session without paired user message, violating Anthropic alternation [1 participants]