openclaw - 💡(How to fix) Fix fix: sessions.json stale after compaction transcript rotation (deadlock)

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…

After compaction rotates the transcript to a new session file (truncateAfterCompaction: true), sessions.json still points to the old session file. The old file is in a stale state, and subsequent messages deadlock waiting for a session write lock that never releases.

Root Cause

In src/agents/agent-command.ts (~line 1631), when updating the session store after an agent run:

await updateSessionStoreAfterAgentRun({
  cfg,
  contextTokensOverride: agentCfg?.contextTokens,
  sessionId,   // ← BUG: uses the original sessionId from prepareAgentCommandExecution()
  sessionKey,
  ...
});

sessionId here is resolved at the start of the run via prepareAgentCommandExecution(). But during the run, if automatic compaction triggers and truncateAfterCompaction is enabled, rotateTranscriptAfterCompaction() creates a new session file with a new session ID. The run's internal sessionIdUsed tracks this correctly, and it is written to result.meta.agentMeta.sessionId.

However, updateSessionStoreAfterAgentRun ignores result.meta.agentMeta.sessionId and uses the caller's sessionId parameter. Since the caller passes the original (pre-rotation) ID, sessions.json is never updated to reflect the new session file.

Fix Action

Fix

One-line fix in src/agents/agent-command.ts:

- sessionId,
+ sessionId: result?.meta?.agentMeta?.sessionId ?? sessionId,

Code Example

await updateSessionStoreAfterAgentRun({
  cfg,
  contextTokensOverride: agentCfg?.contextTokens,
  sessionId,   // ← BUG: uses the original sessionId from prepareAgentCommandExecution()
  sessionKey,
  ...
});

---

- sessionId,
+ sessionId: result?.meta?.agentMeta?.sessionId ?? sessionId,
RAW_BUFFERClick to expand / collapse

Summary

After compaction rotates the transcript to a new session file (truncateAfterCompaction: true), sessions.json still points to the old session file. The old file is in a stale state, and subsequent messages deadlock waiting for a session write lock that never releases.

Root Cause

In src/agents/agent-command.ts (~line 1631), when updating the session store after an agent run:

await updateSessionStoreAfterAgentRun({
  cfg,
  contextTokensOverride: agentCfg?.contextTokens,
  sessionId,   // ← BUG: uses the original sessionId from prepareAgentCommandExecution()
  sessionKey,
  ...
});

sessionId here is resolved at the start of the run via prepareAgentCommandExecution(). But during the run, if automatic compaction triggers and truncateAfterCompaction is enabled, rotateTranscriptAfterCompaction() creates a new session file with a new session ID. The run's internal sessionIdUsed tracks this correctly, and it is written to result.meta.agentMeta.sessionId.

However, updateSessionStoreAfterAgentRun ignores result.meta.agentMeta.sessionId and uses the caller's sessionId parameter. Since the caller passes the original (pre-rotation) ID, sessions.json is never updated to reflect the new session file.

Reproduction

  1. Set compaction.truncateAfterCompaction: true
  2. Have a session that triggers automatic compaction (token budget exceeded)
  3. After compaction rotates the transcript, send another message
  4. Observe: sessions.json points to old session file → new run tries to acquire lock on old file → timeout → deadlock

Fix

One-line fix in src/agents/agent-command.ts:

- sessionId,
+ sessionId: result?.meta?.agentMeta?.sessionId ?? sessionId,

Impact

Any session with truncateAfterCompaction: true that triggers automatic compaction during a run. The /compact command path is unaffected (it uses incrementCompactionCount which handles newSessionId correctly).

Version

2026.5.22

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 fix: sessions.json stale after compaction transcript rotation (deadlock)