openclaw - 💡(How to fix) Fix message tool outbound delivery-mirror triggers EmbeddedAttemptSessionTakeoverError within same run

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…

Error Message

[diagnostic] lane task error: lane=main durationMs=25690 error="EmbeddedAttemptSessionTakeoverError: session file changed while embedded prompt lock was released: C:\Users\Administrator.openclaw\agents\main\sessions\85d97e3d-7f9e-4f3a-a24a-649911ef2ecf.jsonl"

Root Cause

The delivery-mirror write in src/infra/outbound/deliver.ts:1817 calls appendAssistantMessageToSessionTranscript() directly after outbound delivery completes. This write path does not go through the embedded runner's sessionLockController.withSessionWriteLock(), so it changes the session file's fingerprint (mtime/size/ino) without the lock controller knowing. When the embedded runner next calls assertSessionFileFence(), the fingerprint mismatch is detected and EmbeddedAttemptSessionTakeoverError is thrown.

The same class of bug as #84583 (cron announce), but triggered by an entirely different path: the same run's own tool execution producing an outbound delivery that mirrors back to its own session file.

Fix Action

Fix / Workaround

  • #84583 — same error class, different trigger (cron announce delivery)
  • src/agents/pi-embedded-runner/run/attempt.session-lock.ts — lock controller and fingerprint fence
  • src/infra/outbound/deliver.ts:1810–1824 — delivery-mirror write path
  • src/auto-reply/reply/dispatch-from-config.ts:573–592 — internal source reply mirror path

Code Example

{
  "type": "message",
  "timestamp": "2026-05-21T09:27:42.739Z",
  "message": {
    "role": "assistant",
    "provider": "openclaw",
    "model": "delivery-mirror",
    "content": [{"type": "text", "text": "IMG_20211007_144425_50.jpg, IMG_20211007_144712_50.jpg"}]
  }
}

---

[diagnostic] lane task error: lane=main durationMs=25690
  error="EmbeddedAttemptSessionTakeoverError: session file changed while embedded prompt lock was released:
  C:\Users\Administrator\.openclaw\agents\main\sessions\85d97e3d-7f9e-4f3a-a24a-649911ef2ecf.jsonl"
RAW_BUFFERClick to expand / collapse

Problem

When the model invokes the message tool with action: "send" and media attachments (images) during a run, the outbound delivery pipeline writes a delivery-mirror entry to the session transcript bypassing the embedded runner's session lock controller. This causes EmbeddedAttemptSessionTakeoverError and the run fails with:

Something went wrong while processing your request. Please try again, or use /new to start a fresh session.

Root cause

The delivery-mirror write in src/infra/outbound/deliver.ts:1817 calls appendAssistantMessageToSessionTranscript() directly after outbound delivery completes. This write path does not go through the embedded runner's sessionLockController.withSessionWriteLock(), so it changes the session file's fingerprint (mtime/size/ino) without the lock controller knowing. When the embedded runner next calls assertSessionFileFence(), the fingerprint mismatch is detected and EmbeddedAttemptSessionTakeoverError is thrown.

The same class of bug as #84583 (cron announce), but triggered by an entirely different path: the same run's own tool execution producing an outbound delivery that mirrors back to its own session file.

Reproduction timeline (from gateway.log + trajectory + session transcript)

All times UTC:

TimeEvent
09:27:24.359prompt.submitted — embedded runner releases session write lock, saves file fingerprint
09:27:28–40Model streams back, tool calls execute (search_memory, document downloads). Each write goes through withSessionWriteLock — fingerprint stays valid
09:27:40.582Model returns final message tool call: action: "send" with 2 image attachments
09:27:40–42Outbound delivery pipeline uploads images to Feishu, sends message
09:27:42.739Delivery completes → deliver.ts:1817 writes delivery-mirror to session file, bypassing session lock controller
09:27:47.613Embedded runner detects fingerprint mismatch → EmbeddedAttemptSessionTakeoverErrorsession.ended status=cleanup

Evidence

Session transcript line 42 (the intruding write):

{
  "type": "message",
  "timestamp": "2026-05-21T09:27:42.739Z",
  "message": {
    "role": "assistant",
    "provider": "openclaw",
    "model": "delivery-mirror",
    "content": [{"type": "text", "text": "IMG_20211007_144425_50.jpg, IMG_20211007_144712_50.jpg"}]
  }
}

Trajectory for the failed run (runId: a163d9c6):

  • prompt.submitted at 09:27:24.359
  • No model.completed event
  • session.ended at 09:27:47.613 with status: cleanup

Gateway log:

[diagnostic] lane task error: lane=main durationMs=25690
  error="EmbeddedAttemptSessionTakeoverError: session file changed while embedded prompt lock was released:
  C:\Users\Administrator\.openclaw\agents\main\sessions\85d97e3d-7f9e-4f3a-a24a-649911ef2ecf.jsonl"

Expected behavior

Outbound delivery-mirror writes triggered by tool execution within the same run should either:

  1. Go through the run's sessionLockController.withSessionWriteLock(), or
  2. Be deferred until after the run completes and the lock is properly held, or
  3. Update the session lock controller's fingerprint fence after writing

Environment

  • OpenClaw 2026.5.19
  • Feishu channel, direct message
  • Model: gpt-5.4 via vllm provider
  • Windows Server (gateway)

Related

  • #84583 — same error class, different trigger (cron announce delivery)
  • src/agents/pi-embedded-runner/run/attempt.session-lock.ts — lock controller and fingerprint fence
  • src/infra/outbound/deliver.ts:1810–1824 — delivery-mirror write path
  • src/auto-reply/reply/dispatch-from-config.ts:573–592 — internal source reply mirror path

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

Outbound delivery-mirror writes triggered by tool execution within the same run should either:

  1. Go through the run's sessionLockController.withSessionWriteLock(), or
  2. Be deferred until after the run completes and the lock is properly held, or
  3. Update the session lock controller's fingerprint fence after writing

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING