Skip to content

[Bug]: Session exceeding context window produces silent empty replies — no compaction triggered #14064

@cszhouwei

Description

@cszhouwei

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.2 via OpenRouter
  • Config: compaction.mode: "safeguard"

Steps to Reproduce

  1. Use a long-running session with many tool calls, memory_search results, and subagent completions
  2. Session transcript grows to ~312k input tokens
  3. At some point, prompt cache invalidates (cacheRead drops from ~260k to 0), causing full input to be sent
  4. Model returns: content: [], output: 0, stopReason: "length"
  5. Every subsequent message in the same session gets the same empty response
  6. Setting agents.defaults.contextTokens: 200000 and 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:

  1. Overflow recovery: model returns a context overflow error → compact → retry
  2. Threshold maintenance: after a successful turn, when contextTokens > contextWindow - reserveTokens

Neither fires in this scenario:

  • Overflow recovery doesn't fire because stopReason: "length" with output: 0 is 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:

  1. Pre-flight compaction: When a session is loaded and its estimated token count exceeds contextWindow - reserveTokens (or the contextTokens cap), auto-compact before sending the request to the model.
  2. 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.
  3. 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.bak

Then send a new message to create a fresh session.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingstaleMarked as stale due to inactivity

    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