[BUG] Fable 5 gated behind usage credits dialog on Max when authenticated via claude setup-token (inference-only scope cannot read entitlements)

Status Open
Reported on v2.1.215
Maintainer reply ✓ Yes — bcherny
Activity 18 comments · opened Jul 20, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Environment

  • Claude Code version: 2.1.215 (reproduced in both the VS Code extension and Cursor, same extension version)
  • Platform: macOS (Darwin 24.6.0), Apple Silicon
  • Plan: Max, personal account, active
  • Auth method: long lived token from claude setup-token, exported as CLAUDE_CODE_OAUTH_TOKEN

Description

Since the July 20 Fable 5 entitlement change (Fable 5 included on Max at 50% of weekly limits), every Claude Code session authenticated with a setup-token shows this dialog when selecting Fable 5:

Continue on Fable 5 with usage credits? Fable 5 runs on usage credits, billed separately from your plan. Your other models remain included in your plan.

The account is Max, and the claude.ai account page explicitly says: "Fable 5 is still included with your Max plan. If you see a prompt to set up usage credits for it, restart Claude Code."

Restarting fixes sessions authenticated via interactive /login (confirmed on a second account on the same machine). It never fixes setup-token sessions. Minting a brand new setup-token also does not help, the fresh token behaves identically.

Root cause analysis

Setup-token tokens carry only the user:inference scope, and the entitlement endpoints reject that scope, so the client cannot read plan inclusion and falls back to the usage credits dialog on every session:

  • GET https://api.anthropic.com/api/oauth/usage returns 403: OAuth token does not meet scope requirement user:profile (request id req_011CdD1oibooS4x3daMf3CT2)
  • GET https://api.anthropic.com/api/oauth/claude_cli/roles returns 403 with the same scope error (request id req_011CdD1ojqDYFMGL4TivBxZp)
  • GET https://api.anthropic.com/api/oauth/profile returns 403: OAuth token does not meet scope requirement any_of(user:profile, user:office)

Meanwhile the server side entitlement is fine. A direct POST https://api.anthropic.com/v1/messages with model: claude-fable-5 and the exact same token succeeds normally (message id msg_011CdD21nTZaN1k5FchgRmWo), so the account is entitled to Fable 5 and the gate is purely client side.

Steps to reproduce

  1. On a Max account, generate a token with claude setup-token.
  2. Launch Claude Code with CLAUDE_CODE_OAUTH_TOKEN set to that token.
  3. Select Fable 5.
  4. The usage credits dialog appears. Restarting, relaunching, or re-minting the token does not change anything.

Expected behavior

Sessions authenticated via setup-token should honor the account's actual plan entitlement, which the server already knows and enforces. Either let these tokens read plan inclusion (a broader scope option on claude setup-token, or an entitlement endpoint that accepts user:inference), or fail open and let the server decide, instead of presenting a misleading billing prompt to a subscriber whose plan includes the model.

Related issues

#76237 (Fable 5 missing on Max, hasAvailableSubscription false), #74051 (Fable 5 blocks on usage credits, ignoring allowance), #22450 (setup-token lacks user:profile scope for /usage)

View original on GitHub ↗

18 Comments

maxamly · 1 month ago

Workaround from codex lol

Claude-Code-Fable-OAuth-Fix.md

lslzl3000 · 1 month ago

will it be fixed in next release?

lslzl3000 · 1 month ago
Workaround from codex lol Claude-Code-Fable-OAuth-Fix.md

It cannot work on a Ubuntu Linux server

lslzl3000 · 1 month ago
> Workaround from codex lol > Claude-Code-Fable-OAuth-Fix.md It cannot work on a Ubuntu Linux server

Claude-Code-Fable-OAuth-Fix-Linux.md

Use claude 4.8 to find the patch code for Linux

jindrichsirucek · 1 month ago

Opus 4.8 made the workaround working also on 2.1.217
thx for sharing @maxamly

pocketken · 1 month ago

FWIW, another workaround is to just tell Opus/Sonnet to spawn Fable and it "works".

gigamonkey · 1 month ago

Man. This sure is a bummer. I built a whole tool around setup-token and now it's just hosed. According Opus this is because inference tokens that you get from claude setup-token don't have the right to ask the Claude server what you're entitled to so the client fails closed as if you weren't paying $200/month and instead offers you Fable on usage credits and Sonnet. Cool cool cool.

[edit] (Oh, I guess the OP already gave us this analysis.)

Williamleejx · 1 month ago

I also face this issue. Please fix it!

gigamonkey · 1 month ago
AndrewLuebke · 1 month ago

Workaround that keeps the setup-token (no /login required) — relevant to everyone here on the inference-only-scope path. Credit @vzellmeister (#79597): the interactive gate reads subscriptionType from an env var when a token is set, so you can just declare it. Add these next to your CLAUDE_CODE_OAUTH_TOKEN export:

export CLAUDE_CODE_SUBSCRIPTION_TYPE=max
export CLAUDE_CODE_RATE_LIMIT_TIER=default_claude_max_20x   # or default_claude_max_5x — your tier

Start a fresh session → /model fable selects cleanly, and the header flips "Claude API" → "Claude Max". Confirmed on Max 20x / 2.1.220 (Linux).

SUBSCRIPTION_TYPE=max is the lever; RATE_LIMIT_TIER only affects /upgrade text — and don't read your tier from the setup-token's ~/.claude.json, it's stale under token auth (mine wrongly said 5x when I'm 20x). @gigamonkey — this should un-hose the setup-token tool.

pjlsergeant · 1 month ago
Workaround that keeps the setup-token (no /login required) — relevant to everyone here on the inference-only-scope path.

You amazing human, this works great

folknor · 1 month ago

Very nice work, thank you for the solution!

The only thing remaining now is /usage 😂

gigamonkey · 1 month ago

@AndrewLuebke nice!

AndrewLuebke · 1 month ago

@folknor glad it worked! On /usage — worth clarifying, since it trips people up:

  • If you mean the dollar figure: that's a notional number, not a bill. It's what those tokens would have cost pay-as-you-go, but $0 is actually charged — Fable (and everything else) is covered by your Max plan's weekly limits. Claude Code's own docs call the /usage cost an estimate that "may differ from your actual bill," and under a subscription it isn't billed per-token at all. The panel just never says "$0 charged," so it reads like an invoice when it's really a "value consumed against your plan" meter.
  • If you mean the missing plan-limit bars: that's the setup-token's inference-only scope — it can't read the profile/entitlement endpoint (the same user:profile 403 behind this whole bug), so /usage can't draw your gauge bars. Read your real limits from claude.ai → Settings → Usage instead; they're account-wide, so any logged-in surface shows the same numbers.

Either way it's cosmetic — nothing is actually being charged to credits.

folknor · 1 month ago

@AndrewLuebke Thank you, yes I'm aware of how to check the usage on claude.ai. The problem is I dont have daily access to the email that pays for this subscription. That's also why I use setup-token.

AndrewLuebke · 1 month ago

Fair point — and honestly that's the strongest argument for fixing this properly rather than routing around it: people reach for a setup-token because they don't have interactive access to the owning account, so "just check claude.ai" isn't actually available to them. The token is their only handle on the plan, and right now it can't read the entitlement/limit endpoint (the same user:profile 403 behind this whole issue), so /usage can't draw the limit bars.

So +1 to a real fix: give setup-token auth a server-side way to read entitlements/limits (one that doesn't require user:profile), so /usage surfaces the plan gauges locally for exactly the delegated-access case setup-tokens exist to serve.

bcherny collaborator · 14 days ago

Thanks for the unusually thorough report — the root-cause analysis is correct.

What I could verify on 2.1.233 (Linux): claude setup-token requests an inference-only authorization, and tokens minted that way cannot read plan/entitlement information. Sessions authenticated with such a token therefore don't know the account's plan tier, so the plan-inclusion check that a normal /login session refreshes on restart can never succeed there, and the client falls back to the usage-credits prompt as the conservative default. That matches exactly what you're seeing, including why restarting fixes /login sessions but never setup-token sessions. (I couldn't run the full end-to-end repro here since it needs a Max-account setup-token, so this is confirmed by analysis rather than reproduction.)

Classifying as a bug: a recent release (see the changelog, 2.1.227) fixed the sibling case where flags were evaluated without the subscription tier on an expired login, but inference-only tokens structurally never have tier info, so that fix doesn't cover this path. We're looking at either letting these tokens read plan inclusion or not gating them client-side and letting the server decide billing.

Workaround for now: use interactive /login on affected machines.

🤖 Generated with Claude Code

AndrewLuebke · 12 days ago

@bcherny thank you — confirming the root cause and classifying it as a bug is exactly what this thread needed. Your two candidate fixes both address it; one note on which is more complete, plus a client-side workaround for people who land here before either ships.

Why "let the server decide billing" (b) is the stronger fix than "let inference-only tokens read plan inclusion" (a): the same user:profile 403 that blocks the plan-inclusion check also blocks the /usage limit gauges under a setup-token (they never draw). Option (b) sidesteps the profile fetch entirely for the entitlement decision; option (a) only fixes the Fable gate unless it also exposes limits. And the population this bites hardest is delegated access — people use a setup-token precisely because they don't have interactive account access (see @folknor upthread: the account is owned by an email they can't check daily). For them, the "use interactive /login" workaround isn't available, and neither is "check claude.ai."

Client-side workaround that unblocks the picker without /login or re-auth — since the gate reads subscriptionType and the resolver builds it from an env var when CLAUDE_CODE_OAUTH_TOKEN is set, declaring it in ~/.claude/settings.json clears the wall:

"env": {
  "CLAUDE_CODE_SUBSCRIPTION_TYPE": "max",
  "CLAUDE_CODE_RATE_LIMIT_TIER": "default_claude_max_20x"
}

Truthful for a Max account, client-side only, no auth or billing change (headless -p already worked). Match RATE_LIMIT_TIER to your real tier; SUBSCRIPTION_TYPE has to be the literal max for the check regardless of plan. On a couple of 2.1.224+ builds Fable then disappears from /model instead of showing the wall (@jatingartan upthread) — if that happens, adding ANTHROPIC_CUSTOM_MODEL_OPTION / _NAME / _DESCRIPTION restores the picker row.

Durability data point (Linux, Max 20x, setup-token): with just the two env vars above, Fable has stayed selectable and ungated continuously across 2.1.222 → 2.1.226 → 2.1.235 — no re-auth, and I've never needed the custom-model-option add-on on this box. So the env workaround holds on current builds; it's a stopgap, not a substitute for the server-side fix, which is still owed for the reason above — the delegated-access case setup-tokens exist to serve.