Persistent HTTP 429 on auto-mode classifier (xml_s1), account-side config
⚠️ UPDATE (June 2026) — ROOT CAUSE FOUND; the analysis below is superseded. This is not an account-side classifier-pool problem (the theory argued at length in this thread). The real cause is the client-side bug #64585 — disablingCLAUDE_CODE_ATTRIBUTION_HEADER(=0/false) silently 429s the auto-mode safety classifier on capable models (opus/sonnet). Fix: unset that env var to return the header to its default, and the classifier works directly, no proxy. Confirmed by A/B on Claude Code 2.1.187. Closed in favor of #64585 — leaving this thread for history.
---
Update 2026-05-18: Still reproducing on Claude Code 2.1.144 (released 2026-05-19, ~12 hrs before filing). The 2.1.144 changelog contains no auto-mode-classifier model-selection or 429 fix. The 2.1.139 evidence below remains the cleanest on-record repro; nothing about the mechanism has changed across 2.1.139 → 2.1.144.
What's happening
On my Max account, every Claude Code auto-mode safety classifier call to claude-opus-4-7 is returning HTTP 429 rate_limit_error immediately (~1.5–2 s round-trip), at stage=xml_s1. The user-facing message that Claude Code surfaces translates this to "claude-opus-4-7 is temporarily unavailable, so auto mode cannot determine the safety of Bash right now", which is misleading — the underlying response is a 429 from /v1/messages on the classifier code path.
This is not a transient Messages-API rate limit:
- Regular
/v1/messagescalls toclaude-opus-4-7from the same account, same authenticated session, succeed with HTTP 200 within minutes of the classifier 429s. - I have 46 distinct classifier-path 429s in today's
CLAUDE_CODE_DEBUG_LOGS_DIRdebug logs alone. - The same failure pattern persisted yesterday on a day with much lighter Opus usage.
It looks like an account-side misconfiguration: either a feature flag (tengu_auto_mode_config.model is unset in my GrowthBook profile, so the classifier falls through to the session model = Opus 4.7, which is then gated), or a per-account auto-mode-classifier rate-limit pool sized at ~0.
Same-minute proof this isn't a Messages-API pool exhaustion
All from today, 2026-05-12, same account:
| Time UTC | Request shape | Model | Result | ID |
|---|---|---|---|---|
| 15:32:10 | /v1/messages source=side_query classifier stage=xml_s1 | claude-opus-4-7 | HTTP 429 rate_limit_error, 1859ms | req_011Caxv75pXzufzvkvVBwP2d |
| 15:32:15 | /v1/messages source=side_query classifier stage=xml_s1 | claude-opus-4-7 | HTTP 429, 1904ms | req_011Caxv7SqqB7kP3QsyARBJB |
| 16:15:11 | /v1/messages source=sdk normal chat | claude-opus-4-7 | HTTP 200, returns "READY" | 219a8af6-b14d-4b42-98d4-1b255cdceddf (client) |
| 16:15:53 | /v1/messages source=sdk normal chat | claude-opus-4-7 | HTTP 200, returns "WORKING" | 2b35c463-8e94-4d60-b2e6-f083e644d3aa (client) |
If my Messages-API rate-limit pool were exhausted, the chat calls would 429 too — they don't. Different request shape, different gate, only one of them firing.
Binary-level isolation
The classifier-model selection lives in the ME7() function in the Claude Code binary (minified name, body invariant in v2.1.139):
function ME7(){let H=J$("tengu_auto_mode_config",{});if(H?.model)return H.model;return G4()}
When tengu_auto_mode_config.model is unset (my case), it falls through to G4() which resolves to the session model — claude-opus-4-7 for me.
I patched the binary in-place to hardcode the classifier model and re-ran the same probe (zoxide --version — not in my Bash allowlist, so it requires classifier escalation):
| Patched classifier model | Classifier outcome |
|---|---|
| claude-opus-4-7 (unpatched / default) | HTTP 429 rate_limit_error |
| claude-sonnet-4-6 | "temporarily unavailable" (consistent with the Max-plan classifier-model restriction in support's checklist response) |
| claude-haiku-4-5 | outcome=ok in 933–1460 ms |
So the classifier endpoint accepts and serves my account's requests fine. Only the claude-opus-4-7 classifier code path is gated on my account.
A coworker on a comparable Max + Opus 4.7 setup is not affected.
Auto-mode gate check passes (so it isn't a precondition failure)
From my own CLAUDE_CODE_DEBUG_LOGS_DIR:
[auto-mode] verifyAutoModeGateAccess: enabledState=opt-in disabledBySettings=false
model=claude-opus-4-7 modelSupported=true disableFastModeBreakerFires=false
carouselAvailable=true canEnterAuto=true
canEnterAuto=true. Claude Code is not reporting auto mode as unavailable; the client happily enters auto mode. The failure is downstream of the gate, in the classifier API call itself.
Preconditions I've cleared
- Plan: Max (
organizationType: "claude_max", tierdefault_claude_max_20x) - Model:
claude-opus-4-7(per Max-plan auto-mode requirement) - Provider: Anthropic API only (no Bedrock/Vertex/Foundry env vars)
- Claude Code: originally captured on 2.1.139; still reproducing on 2.1.144 (both well past the 2.1.83 minimum)
skipDangerousModePermissionPrompt: true
Reproducer
mkdir -p /tmp/cc-check
CLAUDE_CODE_DEBUG_LOGS_DIR=/tmp/cc-check claude --print --debug api \
--permission-mode auto --model claude-opus-4-7 \
'Run the bash command `zoxide --version` exactly as-is and report what it printed.'
grep -E 'classifier_request|errorKind' /tmp/cc-check/*.txt
Expected: classifier_request_finished ... outcome=ok ...
Observed on my account: classifier_request_finished ... outcome=error ... errorKind=Error:429
Substitute any Bash command that isn't in your local allowlist.
What I've already ruled out
- The
[1m]suffix-propagation bug (#38537) — happens equally with and without suffix - Effort level —
low/medium/high/xhigh/maxall 429 identically CLAUDE_CODE_EFFORT_LEVELenv var — unsetting it doesn't change behaviourANTHROPIC_DEFAULT_OPUS_MODELalias remap — classifier sends explicit model ID, not alias- Patching
cachedGrowthBookFeatures.tengu_auto_mode_config.modelin~/.claude.json— overwritten on next GrowthBook refresh - Local proxy via
ANTHROPIC_BASE_URL— disables classifier entirely (dacEnabled=n/a, per cc-switch#1678)
What I'm asking for
In order of preference:
- An engineer to look at my account's GrowthBook
tengu_auto_mode_configflag value and either setmodelto the correct value, or fix the classifier rate-limit pool sizing for my account. - Documentation of the auto-mode-classifier rate-limit pool in https://docs.claude.com/en/api/rate-limits so users can self-diagnose. Today's docs don't mention it.
- Fix the misleading "temporarily unavailable" error message so it surfaces the actual underlying error (429
rate_limit_error).
Happy to share the full debug log bundle privately. I have already opened a support chat (conversations 215474274160046 and 215474274097794) but Fin's auto-template repeatedly terminates the chat with the "usage limit" stock response, blocking further reply. Hence this issue.
Related
- #49837 — Auto Mode Classifier uses Opus 4.7 instead of Sonnet (this is the mechanism)
- #49478 — claude-opus-4-7 temporarily unavailable blocks auto mode (this is the visible symptom)
- #38537 — Suffix-propagation bug (related but separate; ruled out as my cause)
15 Comments
Found 2 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Update — cross-referencing @akerckhofs's resolution on #49254 (https://github.com/anthropics/claude-code/issues/49254#issuecomment-4312917353), where
DISABLE_TELEMETRY=1blocked GrowthBook refresh and left their account with atengu_auto_mode_configthat had nomodelfield, causing the sameME7()fallthrough to the session model.That mechanism — GrowthBook delivering a
tengu_auto_mode_configwithout amodelfield — is exactly what's happening here, but the cause is different. My telemetry is enabled, not disabled, and the GrowthBook cache is fresh.Inspected
~/.claude.jsonjust now:CLAUDE_CODE_ENABLE_TELEMETRY=1(opposite of akerckhofs's setup)cachedGrowthBookFeatures: 256 flags, last refresh2026-05-21T09:53:27Z— current, not stalecachedGrowthBookFeatures.tengu_auto_mode_config:``
json
``{ "enabled": "disabled" }
No
modelfield.ME7()doesif (H?.model) return H.model; return G4()— so this object falls through toG4()→ session model =claude-opus-4-7→ 429.So same end state as akerckhofs (no
modelin delivered config), but the GrowthBook server is actively delivering this incomplete config to my account on every refresh, rather than the client serving a stale cache. That moves the bug from client (telemetry-cache-staleness) to server (GrowthBook flag delivery) for my case.Bonus inconsistency worth flagging: the delivered config says
"enabled": "disabled", but Claude Code's own auto-mode gate check reportscanEnterAuto=true(see debug-log excerpt in the original report). Either the gate check ignores theenabledfield, or it's evaluated at a different layer thanME7(). Either way it suggeststengu_auto_mode_configis being assembled/delivered inconsistently for my account.Concrete ask, refined: please inspect what GrowthBook is configured to serve for
tengu_auto_mode_configto accountaguynamedryan/ org5b828240-385c-4a3c-860b-c95bffbda30e— both the rule that matches and the value it returns. The two observable symptoms (nomodel,enabled: "disabled") both point upstream of the client.Additional precedent — #44101 is direct evidence that the GrowthBook server can deliver a complete
tengu_auto_mode_configto other accounts, mine just isn't getting one.That issue's reporter (Team plan, Sonnet 4.6) inspected
~/.claude.jsonand found:Three fields, including the
modelthatME7()checks for. My Max account (with telemetry enabled and GrowthBook cache fresh — 256 flags, refreshed today) is delivered:One field, no
model, notwoStageClassifier. Same flag, different payloads, different accounts.So the GrowthBook flag itself is configurable enough to return a full classifier config — it just isn't returning one for my account. That moves this from "Claude Code client bug" to "GrowthBook rule for account
aguynamedryan/ org5b828240-385c-4a3c-860b-c95bffbda30eis misconfigured."Concrete diagnostic ask, narrowed: what's the GrowthBook rule that's matching my account for
tengu_auto_mode_config, and why does it return{enabled: disabled}instead of the full{enabled, twoStageClassifier, model}payload that #44101's reporter receives? Symmetric inspection of both accounts' matched rules should make the misconfiguration obvious.Update — re-tested today (2026-05-21) on Claude Code 2.1.146 with a wire-level proxy intercepting outbound
/v1/messagestraffic, with the binary un-patched (ME7returns the session model as it would by default).Confirmed: Haiku is the only working classifier model for this account
Same patch-matrix results as 5/12, now via a different intercept point (proxy rewrites the
modelfield in-flight rather than changing what the client sends):| Classifier model (proxy-swapped) | Classifier outcome |
|---|---|
|
claude-opus-4-7(no swap, default) | HTTP 429rate_limit_error||
claude-sonnet-4-6(proxy-swapped) | HTTP 429rate_limit_error,durationMs=2618||
claude-haiku-4-5(proxy-swapped) |outcome=ok durationMs=1198|The wire-level reproduction matters because it isolates the restriction from any binary-patch artifact: the proxy doesn't change Claude Code's behavior, only the
modelvalue the upstream API receives. Soclaude-sonnet-4-6returning 429 here is upstream rejecting Sonnet as a classifier model for this account, not a client-side quirk. Haiku is the only model the classifier endpoint will serve for me.Also, importantly, no
dacEnabled=n/ain the debug log this time — theANTHROPIC_BASE_URL-disables-classifier behavior I cited as ruled out in the original report was actually a side-effect of the binary patch, not ofANTHROPIC_BASE_URLalone. Worth correcting that ruled-out for the record:ANTHROPIC_BASE_URL+ unpatched binary fires the classifier normally.Binary string evidence of the circuit-breaker check
Found inside 2.1.146:
So
tengu_auto_mode_config.enabled === "disabled"is a real circuit breaker — but on my account it's not firing. The gate-access debug line still saysenabledState=enabledeven though my cachedtengu_auto_mode_configis literally{"enabled": "disabled"}. So the cached value and the value the circuit-breaker check reads against come from different sources. Another symptom of inconsistent state delivery for my account.GrowthBook fetch endpoint
For anyone reading along: GrowthBook flag fetches go directly to
https://cdn.growthbook.io, not throughapi.anthropic.com.ANTHROPIC_BASE_URLdoes not redirect them, so an HTTP proxy targeted at the Messages API can't intercepttengu_auto_mode_configdelivery (would require DNS override + cert MITM). Mentioning it so the next person investigating this doesn't go down the same false trail.Net engineering ask, sharpened
For my account / org
5b828240-385c-4a3c-860b-c95bffbda30e:tengu_auto_mode_config = {"enabled": "disabled"}to my account when other Max/Team accounts (#44101) receive the full{enabled, twoStageClassifier, model}payload?claude-haiku-4-5for my account but 429 onclaude-opus-4-7andclaude-sonnet-4-6(whereas Team accounts in #44101 are configured to use Sonnet)?Update — ~12 hours after the original report. A partial GrowthBook config change landed for my account, but the rate-limit side hasn't moved.
What changed
The cached
tengu_auto_mode_configflipped from:to:
Still no
modelfield, soME7()/OJ7()in 2.1.146 still falls through to the session model (claude-opus-4-7for me).What didn't change
Just retested with everything else reset: unpatched binary, proxy disabled (
unset ANTHROPIC_BASE_URL), fresh Claude Code 2.1.146 session,zoxide --versionas the probe:| Setup | Classifier outcome |
|---|---|
| Direct
claude-opus-4-7(no proxy, no patch) | HTTP 429rate_limit_error,durationMs=1914× 3 attempts || Wire proxy swapping →
claude-sonnet-4-6| HTTP 429rate_limit_error,durationMs=2954|| Wire proxy swapping →
claude-haiku-4-5|outcome=ok durationMs=833|So Opus and Sonnet still 429 identically to the original report. The model-allow / rate-limit pool side of my account's classifier config is unchanged. Haiku-via-proxy remains the only working classifier model.
Why this is informative
Two GrowthBook-side knobs evidently move independently on this account:
tengu_auto_mode_config.enabled— moved (disabled→enabled)Someone has been touching my account's config since the original report (the
enabledflip is not random), but only one of the two knobs the issue identified. Whatever's gating classifier access by model is a separate rule that wasn't touched.Sharpened diagnostic ask
For account / org
5b828240-385c-4a3c-860b-c95bffbda30e:tengu_auto_mode_config.enabledflip suggests someone is investigating — thank you. But there are still two unfixed things: (a) themodelfield is still absent from the delivered config, and (b) the classifier endpoint still 429s on every model exceptclaude-haiku-4-5.tengu_auto_mode_config.modelAND the per-model rate-limit pool sizing for the classifier endpoint? Those are the actually-load-bearing knobs.modelfield on classifier requests toclaude-haiku-4-5on the wire. It's a stopgap; will retire it the moment the upstream config is fixed.For my
claude_maxorg the local config cache hastengu_auto_mode_configas{ "enabled": "enabled", "twoStageClassifier": true }. Replaying a classifier request while changing onlymodelgivesclaude-opus-4-7→ 429,claude-sonnet-4-6→ 429, andclaude-haiku-4-5→ 200. Regular/v1/messagescalls to the same model return 200 in the same minute. I can reproduce the classifier failure with the session model set to Opus 4.7 non-1M and Sonnet 4.6 as well.In practice this means classifier errors do not stop for permission prompts. After a few denied tool calls / retries, Claude continues on without the denied context and often lands on poor solutions. Easy to miss unless you're actively observing.
Corroborating on a Team plan (Claude Code 2.1.156) — and isolating the trigger to the auth/billing channel rather than the model.
Same root failure as this issue, reproduced today on a different plan tier and a newer build, with one extra isolation that I think narrows the cause.
Environment
subscriptionType: team.~/.claude.jsonoauthAccount):seatTier=team_tier_1,organizationRateLimitTier=default_raven,userRateLimitTier=default_claude_max_5x.default_claude_max_20x— it also hits Team.New isolation: same model — API key serves the classifier, the subscription 429s it
Where this issue patched the classifier model (and found Haiku
ok), I instead held the model fixed atclaude-opus-4-8and changed only the auth/billing channel, using--bare(auth becomes strictlyANTHROPIC_API_KEY, bypassing the Team/OAuth subscription):| Auth channel — same Mac, same binary, same model
claude-opus-4-8, same gated action | classifierxml_s1||---|---|
| Team subscription / OAuth |
outcome=error errorKind=Error:429(10/10, deterministic) || Console API key (
--bare) |outcome=ok durationMs=1981, tool runs, 0×429 |So the Opus classifier code path itself is fine — the endpoint serves
claude-opus-4-8side_queryrequests without issue on API-key billing. The single variable that flips it is the subscription/OAuth channel, which strongly supports your "per-account auto-mode-classifier rate-limit pool sized ~0" reading and locates it specifically on the subscription side. (The same subscription-vs-API-key split shows up for a different feature in #27074.)Model × context matrix (session model = classifier model), on the Team subscription
| Session model | model string in classifier request | result |
|---|---|---|
| claude-opus-4-8 (1M) |
claude-opus-4-8[1m]| 429 || claude-opus-4-8 (200k) |
claude-opus-4-8| 429 || claude-sonnet-4-6 (200k) |
claude-sonnet-4-6| 429 || claude-haiku-4-5 (200k) | (classifier not invoked — falls back to an approval prompt) | no 429 |
Confirms it is not tied to the
[1m]suffix and not Opus-only on the subscription:claude-sonnet-4-6(200k) 429s as well. SameverifyAutoModeGateAccess … canEnterAuto=trueas you — the failure is downstream of the gate.Probe-validity note (for anyone reproducing)
A Bash command covered by a deterministic allow rule (e.g. a read-only
cat <file>) is fast-pathed (permissionDecisionMs≈3) and never invokes the classifier — like yourzoxide(not-in-allowlist) trick, you need a gray-zone action (e.g. writing outside the project scope,touch ~/marker) to force thesource=side_querycall.Sample 429 request_ids (first-party, for server-side lookup)
req_011CbWBZ8w9e3MD5R9ZpPXcB,req_011CbWBiwDyLwphMpxHU7Lsb(claude-opus-4-8),req_011CbWBnoegDgufRuKrieboo(claude-sonnet-4-6). Captured 2026-05-29. Happy to share the full--debugbundle privately.Reproducing on 2.1.158 + Opus 4.8 (native, macOS arm64). I can confirm the account-side / load-independent framing with on-disk forensics plus a binary trace of the model-selection path.
On-disk evidence — the CLI writes every classifier failure to
/tmp/claude-$UID/auto-mode-classifier-errors/<session-id>.txt. A representative one:I have 6 of these spanning 3 days — every one is a
429 rate_limit_erroron the classifier request, with the session model logged asclaude-opus-4-8[1m].Why it lands on Opus, from the binary — the classifier model is selected as
tengu_auto_mode_config.model ?? <session model>. When the account'stengu_auto_mode_config.model(server GrowthBook config) is unset, it falls back to the session model (Opus 4.8) instead of a cheap Sonnet. The classifier request then draws on a near-zero per-account classifier rate-limit pool and 429s on nearly every Bash. The gate is fail-closed, so the result is "auto mode cannot determine the safety of Bash" → all Bash blocked.Load-independent (the key point): this is not token-quota exhaustion. Normal chat requests return 200 in the same minute the classifier returns 429, and it happens on light-usage days. It's a different pool / request shape, not your usage.
No clean local override: on 2.1.158 there's no
settings.json/ env knob that re-points the classifier model (confirmed by grepping the bundle — it's a server-side config). Myenv/settings.json/settings.local.jsonhave nothing relevant set.Not fixed in 2.1.159: I installed 2.1.159 (
nexttag) in isolation and diffed it against 2.1.158 — the auto-mode/classifier string literals and theclassifierModelassignment sites are identical. The upcoming build doesn't touch this.Ask: set
tengu_auto_mode_config.modelto a Sonnet tier for affected accounts (the intended path), or raise the per-account classifier rate-limit pool. Until then the only clean workaround is to leave auto mode — normal / acceptEdits modes issue no classifier call and never 429.Related: #63873 #63819 #49837 #49535 #38618 (and the per-generation precursors #49254 / #49266 for Opus 4.7, both closed
completed— yet the same failure returned with 4.8).Follow-up — cross-version evidence that this is account-side, not model- or profile-specific:
429 rate_limit_erroron Opus 4.6 (claude-opus-4-6[1m]), not just 4.8. The classifier falls back to whatever Opus session model is active, and every Opus tier draws the same near-zero per-account pool. (4.6 request idreq_011CbbD5rGJCtneGTjsEGMCw.)CLAUDE_CONFIG_DIR, same account). Their classifier error logs land in the same/tmp/claude-$UID/auto-mode-classifier-errors/directory, and both 429 — switching profile or Opus version makes no difference.ls; auto mode routes every Bash through the classifier, so reads fail too during the outage.completed) — i.e. it has recurred across 4.6 / 4.7 / 4.8 rather than being fixed.Net: neither switching
CLAUDE_CONFIG_DIRnor changing the Opus version helps. The only client-side escapes are leaving auto mode, or using a Sonnet session model so the classifier falls back to Sonnet. A real fix needs the account-sidetengu_auto_mode_config.modelset to a Sonnet tier.Update — workaround maturing, but the account-config bug is still the root cause (please fix that). Still reproducing on 2.1.159 as of 2026-06-01.
Sharing where I landed, mostly so others hitting this have a recipe — and as a measure of the engineering tax this imposes while the account-side config stays broken.
Evolution — credit where due: this approach isn't mine. @grechman built it first in #49837 — a localhost proxy that fingerprints the classifier by its system prompt and rewrites the model field (github.com/grechman/auto-mode-fix-to-sonnet). I started by binary-patching the model-selection function (
ME7/YtK) just to prove the restriction (opus/sonnet→429, haiku→200), then adopted grechman's proxy shape because it's maintainable: rewrite the classifier sub-call'smodel→claude-haiku-4-5on the wire, foreground untouched.Realities beyond the original workaround:
effort-2025-11-24→effort,context-management-2025-06-27→context_management, …). Strip a header beta whose body field remains →400 "Extra inputs are not permitted". A minimal curl probe returns 200 and hides this; only a realclaude -preproduces it. Safe shape is a blocklist of header-only betas (e.g.context-1m-2025-08-07), never an allowlist.--bare/API-key isolation upthread (same model 200s on API-key billing, 429s on subscription → pool-side, not model-side).ANTHROPIC_BASE_URL(children of a pre-change tmux server, non-interactive shells) sends its classifier direct and 429s — and it's not a rare edge case: ~32 of my ~41 running sessions were escaping the proxy this way until I fixed delivery. @BrownBear127's note that Claude Code logs each failure to/tmp/claude-$UID/auto-mode-classifier-errors/<session>.txtis a great canary (one file per failure, fingerprintable by mode); @javan's point that these 429s don't pause for a permission prompt — they silently degrade output — is why it's worth monitoring. What actually closes it: deliverANTHROPIC_BASE_URLviasettings.jsonenv**, not the shell. In the 2.1.159 binary, settings env is applied withObject.assign(process.env, settingsEnv), so it overrides the inherited shell environment and reaches every process regardless of launch path. (Corollary, if you build a direct-connection fallback: once it's in settings,env -u ANTHROPIC_BASE_URLno longer escapes — you have to remove the key from settings.json.)A stopgap — I'll retire all of it the moment
tengu_auto_mode_config.modelis set (or the per-account classifier pool is sized > ~0) for affected accounts. The ask is unchanged: fix the account-side GrowthBook config; the proxy is just the cost of it staying broken.Code (unsupported, my setup, read before running): https://gist.github.com/aguynamedryan/a7b6bcf6fd9f3a5bb79fcf446000e4df
Update (2026-06-11, re-verified on 2.1.173) — a client-side companion to this just landed (#67542), and it sharpens the ask here.
@PropterMalone's #67542 is a clean binary-level analysis of the client half of this: the auto-mode classifier's model selection (
Rr7in the 2.1.170 bundle) has no availability check and no retry-on-sibling — it targets whatevertengu_auto_mode_configresolves to, and when that model is unavailable it fails closed behind atengu_iron_gate_closedStatsig gate (defaulttrue). They also probe-confirmed what I'd only seen black-box:CLAUDE_CODE_AUTO_MODE_MODELis registered in the env-var table but never consulted — dead.That issue's repro is a capacity event (a model goes temporarily unavailable). This issue is the persistent, capacity-independent sibling — same symptom, but it needs a different fix: a server-side repair of my account's classifier pool, not a client-side fallback or model override (I explain why below).
It's also symptomatically adjacent to the broader capacity-outage cluster (#63873, #63819, #49535) — but distinct from it, not a duplicate: those are transient model unavailability; this account 429s the classifier pool for every model except Haiku with no outage at all (opus/sonnet serve normal
/v1/messages200 in the same minute). A capacity fallback resolves that cluster and would not reach this case — so please don't fold them together.My case has no outage: the per-account classifier pool 429s every model except Haiku
Re-verified today on 2.1.173, classifier request forced onto a direct connection (proxy bypassed):
| classifier
side_querymodel | result ||---|---|
|
claude-opus-4-8[1m]|429/ "temporarily unavailable" (×4 retries) ||
claude-opus-4-7[1m],claude-sonnet-4-6[1m]|429(earlier runs in this thread) ||
claude-haiku-4-5(proxy-rewritten on the wire) |200, action proceeds |The same opus/sonnet models serve normal
/v1/messagestraffic200in the same minute — so this is the classifierside_querypool specifically, not the models. @seishonagon isolated it to the subscription/billing channel upthread: sameclaude-opus-4-8, Team subscription →429(10/10), Console API key via--bare→200(0×429). The per-account classifier pool is sized ~0 on the subscription side.Confirming #67542's #4 directly: with
CLAUDE_CODE_AUTO_MODE_MODEL=claude-haiku-4-5set, today's request still went out asclaude-opus-4-8[1m]. The override is dead.The fix is to repair the pool — not to hand me a knob that pins me to Haiku
I want to be explicit here, because it's easy to mistake my proxy for the desired end state. It isn't. The proxy (rewrites the classifier sub-request's
model→claude-haiku-4-5on the wire; origin @grechman's #49837) forces the classifier onto Haiku only because Haiku is the one model my account's pool will serve. Haiku is the least-capable classifier model, and running safety classification on a weaker model than my session itself uses is a real degradation — I rely on it under duress, not by choice. It's a stopgap, not a solution.So a model-override knob — #67542's fix #2, a live
CLAUDE_CODE_AUTO_MODE_MODEL— would not adequately fix this case: for my account it would only let me pin the degraded Haiku, making the hobbling permanent and official. The actual fix is server-side: restore my account's classifierside_querypool so it serves the capable models (opus/sonnet) — the way it already does for my normal/v1/messagestraffic and, presumably, for other accounts. Repairing that pool is what retires the proxy and lets me classify with a model I actually trust.Side note, verified today on 2.1.173 — scoped allow rules do skip the classifier
#67542 notes auto mode strips
Bash(*)(Ignoring dangerous permission … (bypasses classifier)) and concludes there's no path to run non-read-only Bash during an outage. That holds only for the blanket wildcard. Narrower rules aren't stripped —Bash(ln:*)and a server-scopedmcp__clancey__*both ran on a direct connection with no classifier request emitted. So allowlisting the specific tools you need is a real, more-surgical escape hatch thandisableAutoMode.The ask
For account / org
5b828240-385c-4a3c-860b-c95bffbda30e: repair the per-account classifierside_queryrate-limit pool so it serves the capable models (opus/sonnet). It currently 429s all of them and serves only Haiku — even though those same models return200on my normal/v1/messagestraffic in the same minute. That is the fix, and the only one that lets me run safety classification on the same caliber of model as my session instead of being nailed to the weakest one.For the record, what does not resolve this: a classifier-model override (#67542's fix #2) would only let me pin Haiku — formalizing the degradation, not fixing it; and #67542's capacity-fallback (fix #1) never reaches this case, since there's no outage to fall back from. This is a server-side pool/config defect on my account, and it needs a server-side fix.
Re-verified on 2.1.179 (2026-06-17) — the pool 429 outlived the fix.
A direct classifier request to
claude-opus-4-8[1m](proxy bypassed) still returns429 rate_limit_error—req_011Cc96wyx6mXBLvAUyA7QSp— i.e. the per-account pool, not a529/overload (which is what a transient global Opus outage would be). So 2.1.176's "auto mode classifier now falls back to the best available Opus model" did not reach this case: falling back to the model my pool refuses is no fallback at all. Same429 rate_limit_error, latest release — still no movement on the pool itself.(Cross-ref: #69002 proposes a configurable classifier model. Worth having, but it wouldn't fix this — for my account it would only let me pin Haiku, the weakest classifier model. The pool is the defect, not model selection.)
My 2c, ignore if it doesn't help. I was experiencing 429s exclusively on classifier requests after messing with oMLX and claude.
At some point in the process I configured the env setting
CLAUDE_CODE_ATTRIBUTION_HEADERto0.Once I switched back to cloud models, chat messages were fine and classifier attempts received 429s.
Removing this sorted it for me and I can repro it with the following:
Resolved on my end — and the account-side framing in this thread was a misdiagnosis. Mea culpa.
The cause is client-side: #64585 —
CLAUDE_CODE_ATTRIBUTION_HEADER=0. I had it set (as a prompt-cache optimization), and disabling it is what 429s the auto-mode classifier. Full credit to @JScones, whose comment above put me onto it.Confirmed by A/B today, on a direct connection (proxy bypassed), reading the nested session's own
--debugclassifier log:| direct — only the header changes | header OFF | header ON |
|---|---|---|
|
claude-opus-4-8|429 rate_limit_error|200||
claude-sonnet-4-6|429 rate_limit_error|200|Same model, same endpoint (
api.anthropic.com), the only variable isCLAUDE_CODE_ATTRIBUTION_HEADER. Re-enabling it (just unset the var) makes opus and sonnet classify normally — no proxy, no model override, nothing account-side.So my earlier "per-account classifier pool" analysis was wrong, and I apologize for steering toward a server-side fix. The actual bug is that disabling the attribution header silently breaks the auto-mode safety classifier — chat works, the classifier 429s, and nothing points at the env var as the cause. That's a real footgun worth fixing client-side (the classifier shouldn't 429 just because the attribution block is absent). For anyone else 429ing on the classifier: check whether you've set
CLAUDE_CODE_ATTRIBUTION_HEADER=0, and unset it.Retiring my wire-proxy workaround. Thanks again @JScones.
Closing: root cause is the client-side attribution-header bug (#64585) — re-enabled the header on my end and the opus/sonnet classifier works direct, no proxy. Full A/B analysis in my comment above. Consolidating the signal on #64585.