Skip to content

Long-context downgrade doesn't recognize Claude's '400 You're out of extra usage' and fails instead of retrying at 200k #4065

Open

Description

@code-yeongyu

Summary

On the Claude subscription (Agent SDK) lane, a request that asked for the long-context tier can fail with Claude's generic billing error:

API Error: 400 You're out of extra usage. Add more at claude.ai/settings/usage and keep going.

The long-context downgrade matcher doesn't recognize it. extensions/builtin/anthropic-subscription/errors.ts:114-120 matches only (?:extra usage|usage credits) (?:is|are) required for long context. So instead of retrying at the 200k window, the turn fails, then walks the fallback chain, and the user sees a provider error.

This was seen by a beta user on a build whose engine still appended [1m] to Opus 5/5.5 (#3801, fixed by #3802). After #3802 only legacy ids carry [1m], but any remaining [1m] request (legacy models, or an explicit 1M opt-in) can still hit this.

Expected

When an attempt that requested the long-context tier (a [1m] id) gets this exact 400, it's treated as a long-context refusal: record the refusal and retry once at the 200k window, before visible content, through the same path as the existing refusal (long-context-retry.ts, managed failover). A request that did NOT ask for long context and gets this 400 stays a normal billing failure: no retry, a clear user-facing reason.

Acceptance

  • RED with the EXACT error body above: a [1m] attempt today fails; after the fix it retries at 200k and succeeds (deterministic SDK fake).
  • The same body on a non-[1m] attempt does NOT retry.
  • The existing 'extra usage is required for long context' cases are unchanged.

Related: #3801/#3802, #3751 (refusal wording), #3752, #3753.

Activity

  1. code-yeongyu commented on Oct 23, 2026

    @code-yeongyu
    OwnerAuthor

    Confirmed with a deterministic Agent SDK fake using the exact response in this issue. On the current base (f4620f3250), both ambient and managed [1m] attempts stop after one query rather than retrying with the plain model id at 200k.

    The regression run reported 9 failed, 23 passed across the new issue regression and the existing #3801 request-shape suite. The existing Extra usage is required for long context cases still pass. Additional failing assertions cover the explicit billing classification and a failure that persists after the standard-window retry.

    The fix passes the actual attempt's legacy-window flag to the shared classifier. Both lanes retain their existing pre-visible-content and once-only downgrade path. Requests without [1m] classify this exact response as non-retryable billing and preserve Claude's actionable reason. GREEN validation and normal commit hooks are queued. Evidence held locally.

  2. code-yeongyu commented on Oct 23, 2026

    @code-yeongyu
    OwnerAuthor

    Implemented in #4066, head 0584156c901654d96bd77341b1409b48f679d461.

    The exact committed head passed 73 tests in 7 focused files, including both auth lanes, the exact response, standard-window billing controls, the existing refusal wording, visible-content safety, and the retry limit. The changelog gate passed. Normal commit hooks passed the full root static check, and hermetic real-CLI Anthropic mock-loop QA passed 22/22, with zero real provider calls.

    The PR remains subject to GitHub CI and formal review. Evidence held locally.

  3. code-yeongyu commented on Oct 23, 2026

    @code-yeongyu
    OwnerAuthor

    Note: the premise that a [1m] request is what triggers this billing error is being re-checked from captured requests, since Opus 1M on a subscription should not bill as extra usage. This matcher change (#4066) only affects attempts that explicitly asked for the legacy [1m] tier, but its rationale will be updated once the actual root cause is measured.

  4. code-yeongyu commented on Oct 26, 2026

    @code-yeongyu
    OwnerAuthor

    Linked user report (desktop, 2026.1025.3, Anthropic subscription via OAuth): still failing after reinstall; the desktop provider list also shows an undeletable 'kiro' provider that requests seem to go to (sisyphuslabs/omo-desktop-app#4711). If 'kiro' is a fallback rung in that user's chain, the 'Connection error' shown would be the last rung's failure (this issue's class), not the Claude account's.

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions