Skip to content

Claude: full context fails turns as "blocking_limit" instead of compacting #160

Closed

Description

@mubeda

Summary

A long Claude thread reached 96% of its context window (961,230 of 1,000,000 tokens). Claude reported auto-compact as enabled, yet the next turn failed 4 s after it started, and the chat panel showed only Claude turn failed (blocking_limit). That message doesn't say the context is full or what to do. BiBCode didn't compact or retry. The user had to recognise the cause, type /compact by hand, and resend. Messages sent after the failure queue behind the manual compaction. The profiler recorded nothing for the failed turn.

Environment

Field Value
BiBCode 0.10.2, desktop (AppImage)
OS Omarchy (Arch-based Linux), x86_64
Mode local
Provider Claude Code 2.1.308, stream-json, 1M-token context window
Finding none (provider turn failures raise no profiler finding)

Evidence

  • Thread token usage at 13:25:27 UTC: usedTokens 961,230, maxTokens 1,000,000, compactsAutomatically: true (from Claude's isAutoCompactEnabled).
  • The turn started at 13:30:18 and failed at 13:30:23 UTC. The session is now in error with last_error Claude turn failed (blocking_limit). and last_error_class provider_error.
  • Claude's own transcript for that turn: one synthetic assistant message with isApiErrorMessage: true, error: "invalid_request", text Prompt is too long. The transcript has no compaction boundary, so automatic compaction never ran. It wasn't a failed compaction: Claude then says automatic compaction failed: ….
  • In Claude Code 2.1.308, blocking_limit sits with prompt_too_long and rapid_refill_breaker as the { kind: "stop", cause: "context_limit" } terminal reasons.
  • Profiler events from 13:29 to 13:35 UTC: only server.refreshProviderUsage timings and client batches. Nothing marks the failed turn.

Suspected source

  • apps/server/src/provider/claude/runtime.rs:2654: with no errors and no api_retry error, the message falls back to Claude turn failed (<terminal_reason>)., which turns a context-limit stop into an opaque code.
  • apps/server/src/provider/claude/protocol.rs:86: AssistantMessage doesn't model Claude's error / isApiErrorMessage, so the Prompt is too long text never reaches the failure message.
  • apps/server/src/provider/claude/usage.rs:63: BiBCode already knows usedTokens, maxTokens and compactsAutomatically, but nothing acts on a near-full window.

Reproduction

  1. Run a Claude thread until the context indicator approaches the window (here 96% of 1M).
  2. Send another message.
  3. The turn fails within seconds with Claude turn failed (blocking_limit). Further messages also fail or queue until the user sends /compact.

Root-cause hypothesis

Claude Code stopped at its blocking context threshold without running auto-compact, even though auto-compact was enabled. That part is upstream behavior in headless stream-json mode, and its trigger is unclear. BiBCode treats the stop as a generic provider error, hides the actionable text, and has no recovery path. Confidence: high for the BiBCode handling (code paths above); low for why Claude skipped its own auto-compact.

Suggested fix direction

  • Classify blocking_limit, prompt_too_long and rapid_refill_breaker as a context-limit failure (its own errorClass). Show an actionable message such as "This conversation filled Claude's context window. Compact it to continue.", with a Compact action, and carry Claude's own text (Prompt is too long, or automatic compaction failed: …).
  • Recover automatically: on a context-limit failure, send /compact to the same session once, then redeliver the failed message. If compaction fails too, stop and show the actionable error; never loop. Consider a setting, on by default.
  • Guard proactively: when usedTokens / maxTokens crosses a high threshold (for example 95%) and the turn ends idle, compact before the next turn instead of waiting for Claude's blocking threshold.
  • Profiler coverage: record provider turn failures (redacted: provider, terminal reason, error class) so repeated context-limit stops raise a finding.

Activity

  1. added
    bugSomething is broken or behaving incorrectly.
    on Oct 22, 2026
  2. mubeda commented on Oct 22, 2026

    @mubeda
    OwnerAuthor

    Docs follow-up, checked against the official Claude Code docs on 2026-10-22 (Claude Code 2.1.308, the latest release):

    Field Value
    Claude 2.1.308, latest on npm; no later fix exists
    Usage 961,230 of 1,000,000 tokens, 5 min before the failure

    What is new:

    • Model configuration says native 1M-window models auto-compact at about 967K tokens by default. The thread sat about 6K under that. The next request then crossed the blocking limit, and Claude stopped with blocking_limit without compacting. Root-cause hypothesis (medium): one turn's input carried the conversation past both thresholds at once. Claude's documented recovery (compact, then retry) didn't run in headless stream-json mode.
    • Error reference: in -p/stream-json output the text stays Prompt is too long. The interactive form is Context limit reached · /compact or /clear to continue. BiBCode should show the interactive wording plus a Compact action.
    • More levers for the fix direction: launch Claude with a smaller auto-compact window (--autocompact <tokens> per launch, or CLAUDE_CODE_AUTO_COMPACT_WINDOW) to leave headroom on 1M models. Or compact proactively from the autoCompactThreshold that the context-usage response reports.
    • The adapter-side fields this needs (assistant error, status: "compacting", autoCompactThreshold, terminal_reason classes) are tracked in Claude: adapter ignores Agent SDK error, compacting and threshold fields #161.
  3. mubeda commented on Oct 22, 2026

    @mubeda
    OwnerAuthor

    The recovery proposed here can be provider-generic. Codex app-server 0.163 has thread/compact/start (compact on demand, progress as a contextCompaction item) and reports contextWindowExceeded. OpenCode 2.1 has POST /api/session/{id}/compact and Session.Message.Compaction (running, completed, failed; reason auto or manual). Per-provider gaps: Codex #162 and #163, OpenCode #164.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is broken or behaving incorrectly.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions