-
-
Notifications
You must be signed in to change notification settings - Fork 79.1k
Bug: resuming a session with a corrupted header line silently wipes the entire transcript (data loss) #89037
Copy link
Copy link
Closed
Labels
P0Emergency: data loss, security bypass, crash loop, or unusable core runtime.Emergency: data loss, security bypass, crash loop, or unusable core runtime.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.ClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:data-lossCan lose, corrupt, or silently drop user/session/config data.Can lose, corrupt, or silently drop user/session/config data.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Metadata
Metadata
Assignees
Labels
P0Emergency: data loss, security bypass, crash loop, or unusable core runtime.Emergency: data loss, security bypass, crash loop, or unusable core runtime.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.ClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:data-lossCan lose, corrupt, or silently drop user/session/config data.Can lose, corrupt, or silently drop user/session/config data.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Give feedbackNo fields configured for issues without a type.
Summary
Resuming a session whose first line (the header) is corrupted/partially written causes the entire on-disk transcript to be silently destroyed. The file is truncated to a single fresh session header (with a brand-new id), and every persisted user/assistant message is permanently lost.
This is reachable from any crash, partial write, or disk-full condition that leaves the header line truncated — the header is the first line written to the file, so an interrupted initial flush corrupts exactly the line this code path is fragile to.
openclaw --session <file>,--continue, and any resume path throughSessionManager.open()/setSessionFile()main@0b5be66eRoot cause
loadEntriesFromFile()(src/agents/sessions/session-manager.ts:384) silently skips unparseable lines, then validates only the first successfully parsed entry:If the header line is corrupt it gets skipped,
entries[0]becomes the first message, the header check fails, and the function returns[].setSessionFile()then treats[]as empty/corrupt and overwrites the file:The intent ("recover from a genuinely empty file") is reasonable, but it cannot distinguish "empty file" from "intact conversation whose header line happens to be corrupt", and it destroys the latter.
Reproduction
Standalone vitest against pristine
main:Observed (main @
0b5be66e)Expected
Resuming must never destroy persisted messages. A file with a recoverable body should not be silently overwritten.
Suggested direction
*.corrupt-<ts>.jsonl) before any rewrite, so history is recoverable.type:"session"entry exists anywhere in the parsed entries, use it instead of requiring it at index 0; or synthesize a header and prepend it, preserving the existing message lines.Happy to send a PR with a fix + the regression test above.