fix(anthropic): keep subscription OAuth requests on included billing + auxiliary OAuth fallback - #53213
Closed
mguttmann wants to merge 1 commit into
Closed
Conversation
…+ auxiliary OAuth fallback Subscription OAuth users (source: claude_code, native Anthropic model) hit HTTP 429 "monthly spend limit" on every turn because the request is billed as overage instead of included subscription usage, and after the first 429 all auxiliary tasks fail with "no API key found". - build_anthropic_kwargs: on is_oauth, keep the Claude Code identity block and cap the remaining app system-prompt text (HERMES_OAUTH_SYSTEM_BUDGET, default 3000 chars) so the request stays in the included-subscription lane. Bisection shows the trigger is cumulative app-specific prompt content, not max_tokens or length. Interim mitigation; see linked issue for the cleaner long-term path. - _try_anthropic: fall back to resolve_anthropic_token() when the credential pool is present but has no available entry (OAuth token transiently marked exhausted), so auxiliary tasks keep working on the subscription. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 26, 2026
Contributor
|
Thanks for the concrete investigation and for separating the auxiliary fallback from the OAuth routing hypothesis. Automated hermes-sweeper review found:
If a separately approved prompt-budget control is pursued later, it needs to use the established Closed as not-planned per standing maintainer policy ( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Subscription-OAuth users (
source: claude_code, native Anthropic model) currently get HTTP 429 "monthly spend limit" on every main-agent turn, and — after the first 429 — all auxiliary tasks fail with "no API key found". Full root-cause analysis and bisection evidence in #53212.A subscription token has no spend cap; the 429 means the request is being billed as overage / raw API usage instead of included subscription usage. This PR keeps OAuth requests in the included lane and restores auxiliary calls.
Changes
1.
agent/anthropic_adapter.py— keep OAuth requests in the subscription billing laneThe
is_oauthbranch already prepends the Claude Code identity block and normalizes tool names, but the request is still billed as overage. Bisection (see #53212) shows the trigger is the cumulative amount of app-specific instruction content in the system prompt (skills, mid-turn steering, Computer Use, …):real_prompt[:4000]→ 200,real_prompt[:4500]→ 429, while 18.9k chars of generic text passes. So it is content/structure, not length,max_tokens, or theis_oauthflag.This change keeps the Claude Code identity block (index 0) intact and caps the remaining app system-prompt text to a configurable budget so the request stays in the included-subscription lane:
Trade-off (honest): truncation drops part of Hermes' detailed tool/skill prose from the OAuth system prompt (tool schemas are unaffected, so tool use still works). This is an interim mitigation. The cleaner long-term fix — matching what the
opencode-claude-bridgefamily does — is to send a genuine, classifier-safe Claude Code system prompt on the OAuth path instead of truncating. Happy to rework toward that if maintainers prefer; the env default makes it easy to tune or disable.2.
agent/auxiliary_client.py— OAuth fallback in_try_anthropic(clean bugfix)When the credential pool is present but has no available entry (the only entry is an OAuth credential transiently marked "exhausted" by an earlier 429),
_try_anthropicreturnedNonewithout tryingresolve_anthropic_token(). That disabled every auxiliary Anthropic task (title generation, vision, web_extract, compression, skills_hub, mcp) untilhermes auth reset anthropicwas run manually.Fix: fall back to the resolved OAuth/setup token when no pool entry is available.
_try_openrouter(API-key only),_try_openai_codex(already has_read_codex_tokensfallback) and the generic pool loop are unaffected — only_try_anthropicwas missing it.Testing
Verified against the live API with a real subscription OAuth token (
claude-opus-4-8):429 monthly spend limit;generate_title()→ "no API key found".200, model replies normally;generate_title("hallo", "Moin moin! …")→"Begrüßung und Hilfeangebot"(auxiliary call succeeds on OAuth).is_oauth=False(API-key) path is unchanged — both changes are gated on OAuth / pool-empty.Notes
Fixes the OAuth-billing class of issues tracked in #40014 / #47260. Details: #53212.