Bug Description
After a hook-based compaction (fromHook: true), subsequent prompt attempts crash with:
TypeError: Cannot read properties of undefined (reading 'totalTokens')
The session becomes permanently bricked — every incoming message hits the same error. The only fix is manually archiving the session JSONL file.
Reproduction
This has occurred twice on the same session (same UUID f6ae2fc0-...), both times following the same pattern:
- Session accumulates ~180K tokens of context
- OpenClaw's hook-based compaction fires (visible as
fromHook: true in the compaction entry)
- Compaction completes successfully (summary generated,
firstKeptEntryId set)
- ~30 minutes of silence (no messages)
- Next incoming message immediately crashes with
totalTokens TypeError
- Every subsequent attempt (including model fallback from opus → sonnet) hits the same crash
- Session is permanently stuck until the JSONL file is manually archived
Error Details
From gateway.err.log:
[diagnostic] lane task error: lane=main error="TypeError: Cannot read properties of undefined (reading 'totalTokens')"
[diagnostic] lane task error: lane=session:agent:main:main error="TypeError: Cannot read properties of undefined (reading 'totalTokens')"
Embedded agent failed before reply: Cannot read properties of undefined (reading 'totalTokens')
The error occurs during prompt preparation (before any LLM API call), not during compaction itself.
Session JSONL Analysis
The broken session shows this sequence after compaction:
Line 754: type=compaction tokensBefore=182599 fromHook=true
Line 755: customType=openclaw.cache-ttl
Line 756: customType=openclaw:prompt-error error="Cannot read properties of undefined (reading 'totalTokens')"
Line 757-777: Repeated prompt-error entries (8 total, alternating opus/sonnet attempts)
The kept messages (lines 711-753) include assistant messages with valid usage data — so the issue is not missing usage in the JSONL, but rather how the session state is reconstructed after hook-based compaction.
Likely Root Cause
The error traces to one of two locations:
-
pi-coding-agent/dist/core/compaction/compaction.js:72 — calculateContextTokens(usage) does usage.totalTokens without a null check. The getAssistantUsage() / getLastAssistantUsageInfo() functions are supposed to guard against this, but after hook-based compaction the in-memory message array may not have proper usage data even though the JSONL does.
-
src/auto-reply/reply/session.ts:418 — sessionStore[parentSessionKey].totalTokens could crash if the session store entry is in an inconsistent state after compaction, though this line has a guard check above it.
The key distinguishing factor is fromHook: true — this uses OpenClaw's extension-based compaction path rather than the internal pi-coding-agent compaction. The extension compaction may leave the in-memory session state inconsistent with what's persisted in the JSONL.
Suggested Fix
Add a null/undefined guard before accessing .totalTokens:
// In calculateContextTokens:
export function calculateContextTokens(usage) {
if (!usage) return 0; // Guard against undefined usage
return usage.totalTokens || usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
}
And/or ensure the hook-based compaction path properly reconstructs the in-memory message array with usage data intact.
Environment
- OpenClaw version: latest (installed via npm)
- OS: macOS (Darwin 25.2.0, arm64)
- Model: claude-opus-4-6 (primary), claude-sonnet-4-6 (fallback)
- Node: v25.6.1
- Session type: persistent agent session (agent:main:main)
Workaround
Archive the broken session file to force a fresh session:
mv ~/.openclaw/agents/main/sessions/<session-id>.jsonl \
~/.openclaw/agents/main/sessions/<session-id>.jsonl.bak-$(date +%Y%m%d%H%M%S)
The next incoming message creates a new session automatically.
Bug Description
After a hook-based compaction (
fromHook: true), subsequent prompt attempts crash with:The session becomes permanently bricked — every incoming message hits the same error. The only fix is manually archiving the session JSONL file.
Reproduction
This has occurred twice on the same session (same UUID
f6ae2fc0-...), both times following the same pattern:fromHook: truein the compaction entry)firstKeptEntryIdset)totalTokensTypeErrorError Details
From
gateway.err.log:The error occurs during prompt preparation (before any LLM API call), not during compaction itself.
Session JSONL Analysis
The broken session shows this sequence after compaction:
The kept messages (lines 711-753) include assistant messages with valid usage data — so the issue is not missing usage in the JSONL, but rather how the session state is reconstructed after hook-based compaction.
Likely Root Cause
The error traces to one of two locations:
pi-coding-agent/dist/core/compaction/compaction.js:72—calculateContextTokens(usage)doesusage.totalTokenswithout a null check. ThegetAssistantUsage()/getLastAssistantUsageInfo()functions are supposed to guard against this, but after hook-based compaction the in-memory message array may not have proper usage data even though the JSONL does.src/auto-reply/reply/session.ts:418—sessionStore[parentSessionKey].totalTokenscould crash if the session store entry is in an inconsistent state after compaction, though this line has a guard check above it.The key distinguishing factor is
fromHook: true— this uses OpenClaw's extension-based compaction path rather than the internal pi-coding-agent compaction. The extension compaction may leave the in-memory session state inconsistent with what's persisted in the JSONL.Suggested Fix
Add a null/undefined guard before accessing
.totalTokens:And/or ensure the hook-based compaction path properly reconstructs the in-memory message array with usage data intact.
Environment
Workaround
Archive the broken session file to force a fresh session:
The next incoming message creates a new session automatically.