Skip to content

Bug: orphaned user repair leaves persisted transcript out of sync #76968

@serkonyc

Description

@serkonyc

Summary

When a new prompt arrives while the previous turn left a trailing user leaf, OpenClaw merges that orphaned user content into the next prompt and moves the in-memory SessionManager leaf back to the parent. The file-backed transcript is not rewritten at that point.

That can leave the .jsonl transcript on disk with stale/orphaned user entries that no longer match the active in-memory branch. Later transcript rewrites or branch projections may then produce a current transcript with missing assistant turns or long runs of consecutive user messages, even though earlier backup files still contain those assistant turns.

Observed behavior

In a file-backed agent session:

  • the session registry entry and session .jsonl existed
  • the current transcript contained multiple consecutive user message entries
  • assistant replies that had previously been persisted were no longer present in the active .jsonl
  • backup .jsonl.bak-* files still contained some of the missing assistant entries
  • logs included the orphaned-user repair path:
Merged and removed orphaned user message to prevent consecutive user turns.

Root cause

In src/agents/pi-embedded-runner/run/attempt.ts, the orphaned trailing user repair currently changes only the in-memory leaf:

sessionManager.branch(leafEntry.parentId)
// or sessionManager.resetLeaf()

That does not remove the stale leaf from the persisted transcript file. The next run can start from disk state that still contains the orphan, so disk state, active branch state, and later rewrite/projection behavior diverge.

Expected behavior

When the orphaned user leaf is intentionally removed, the persisted SessionManager state should be updated immediately as well, so the active branch and .jsonl file stay consistent.

Fix direction

Remove the leaf entry from the underlying file-backed SessionManager entries and call its rewrite hook when available. Keep the previous in-memory branch/reset fallback for nonstandard managers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions