-
-
Notifications
You must be signed in to change notification settings - Fork 67.3k
Description
Summary
When a session's accumulated context exceeds the model's effective context window (or the configured contextTokens cap), the model returns stopReason: "length" with output: 0 — producing silent empty replies. Auto-compaction never triggers, leaving the session permanently stuck: every subsequent message gets the same empty response.
Environment
- OpenClaw version:
2026.2.9(main branch) - Model:
openai/gpt-5.2via OpenRouter - Config:
compaction.mode: "safeguard"
Steps to Reproduce
- Use a long-running session with many tool calls,
memory_searchresults, and subagent completions - Session transcript grows to ~312k input tokens
- At some point, prompt cache invalidates (
cacheReaddrops from ~260k to 0), causing full input to be sent - Model returns:
content: [], output: 0, stopReason: "length" - Every subsequent message in the same session gets the same empty response
- Setting
agents.defaults.contextTokens: 200000and restarting the gateway does not help — the existing session is still loaded and sent as-is
Observed Behavior
From the session transcript (.jsonl):
{
"role": "assistant",
"content": [],
"usage": { "input": 311501, "output": 0, "cacheRead": 0, "totalTokens": 311501 },
"stopReason": "length"
}From the debug log:
embedded run agent start: runId=...
embedded run agent end: runId=... ← ~5s later, model "completed"
embedded run done: durationMs=5662 aborted=false
No compaction log, no error log, no Compaction safeguard: warning. The run appears successful from the gateway's perspective, but replies=0.
Root Cause Analysis
Per docs/reference/session-management-compaction.md, auto-compaction triggers in two cases:
- Overflow recovery: model returns a context overflow error → compact → retry
- Threshold maintenance: after a successful turn, when
contextTokens > contextWindow - reserveTokens
Neither fires in this scenario:
- Overflow recovery doesn't fire because
stopReason: "length"withoutput: 0is not treated as a context overflow error — it's treated as a normal (albeit empty) completion. - Threshold maintenance may not fire because the turn produced 0 output tokens, so the runtime may not consider it a meaningful turn that warrants a compaction check.
Additionally, there is no pre-flight check when loading a session: if the existing transcript already exceeds the configured contextTokens cap, the full history is still sent to the model without compaction.
Expected Behavior
At least one of the following should happen:
- Pre-flight compaction: When a session is loaded and its estimated token count exceeds
contextWindow - reserveTokens(or thecontextTokenscap), auto-compact before sending the request to the model. - Detect
output: 0+stopReason: "length"as overflow: Treat this as a context overflow condition and trigger overflow recovery (compact → retry), rather than silently accepting the empty response. - Warn or log the condition: At minimum, log a warning when the model returns 0 output tokens with
stopReason: "length", so the issue is visible in logs.
Workaround
Manually delete or rename the bloated session transcript file:
mv ~/.openclaw/agents/main/sessions/<sessionId>.jsonl \
~/.openclaw/agents/main/sessions/<sessionId>.jsonl.bakThen send a new message to create a fresh session.