Skip to content

feat(agents): detect and recover from consecutive empty model responses (0 output tokens) #14504

@id7368

Description

@id7368

Problem

When a model returns an empty response (0 output tokens, empty content array) without an explicit error, OpenClaw treats it as a successful completion. If this happens repeatedly, the session becomes permanently stuck — every subsequent message gets the same silent empty response, and no failover, retry, or compaction is triggered.

Observed behavior

  1. Model (Claude Opus 4.6 via terminal-pub) returned output: 0 with empty content after a tool call result
  2. Three consecutive empty responses from the same model — no retry, no failover
  3. User manually switched to openrouter/pony-alpha → also empty
  4. Auto-fallback to gemini-3-flash-preview → also empty
  5. Back to claude-opus-4-6 → still empty
  6. All three models cycling through with 0 output tokens, session completely unresponsive
  7. Only recovery: manually clearing the session

Session log excerpt

[14:11:49] assistant (claude-opus-4-6) output=0
[14:12:12] assistant (claude-opus-4-6) output=0
[14:12:23] assistant (claude-opus-4-6) output=0
[14:16:18] assistant (claude-opus-4-6) output=0  # user said 'terminal crashed, continue'
[14:20:19] assistant (claude-opus-4-6) output=0  # user asked 'are you back?'
[14:22:08] assistant (pony-alpha) output=0        # manual model switch
[14:22:11] assistant (gemini-3-flash-preview) output=0  # auto fallback
[14:22:23] assistant (claude-opus-4-6) output=0   # cycled back
[14:24:29] assistant (gemini-3-flash-preview) output=0  # image message
[14:24:54] assistant (gemini-3-flash-preview) output=0  # another image

All timestamps in UTC+8. The session was stuck for ~20 minutes before manual intervention.

Relation to #14157

#14157 addresses the specific case where stopReason === "length" with output: 0 (silent context overflow). This issue covers a broader scenario: any consecutive empty responses regardless of stopReason. In our case, the stopReason may not have been "length" — the models simply returned nothing, possibly due to corrupted context state rather than overflow.

Suggested behavior

  1. Empty response detection: If a model returns 0 output tokens with no error, treat it as a soft failure
  2. Consecutive empty threshold: After N consecutive empty responses (e.g., 2-3), trigger recovery:
    • Attempt auto-compaction (context may be in a bad state)
    • If compaction doesn't help, try failover to next model
    • If all models fail with empty responses, notify the user with a visible error message suggesting /clear or /new
  3. Break the loop: Don't silently accept empty responses indefinitely — at minimum, surface the problem to the user

Environment

  • OpenClaw version: 2026.2.9
  • Primary model: terminal-pub/claude-opus-4-6
  • Fallbacks: google/gemini-3-flash-preview
  • Compaction: safeguard mode, reserveTokensFloor=40000, maxHistoryShare=0.6
  • Context pruning: cache-ttl 15m with hardClear

Disclosure: This issue was filed by an AI assistant (OpenClaw instance) on behalf of its operator @id7368, based on a real production incident. The session logs and analysis were extracted from automated backups.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    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