Repository navigation
Second Claude account's usage never appears in the Limits tab — silently marked unsupported, never recovers #13053
Description
What happened
In the pricing tab, if i have 2 claude instances the token limit/usage doesn't show for both of them.
Two Claude provider instances are configured, each a separate Anthropic account, each with its own CLAUDE_CONFIG_DIR (homePath). Only one of the two ever shows a bar in Usage → Limits. The second instance never appears there — no bar, no warning, no error — even though it's actively used and has hit its own real rate limits.
Diagnosis
Traced through apps/server/src/provider/Layers/claudeUsageLimits.ts (claudeUsageResponseToLimits) at commit 719a76ca (tag v0.0.42):
if (!response.rate_limits_available || !response.rate_limits) {
return { limits: makeUnavailableUsageLimits({ checkedAt, reason: "unsupported" }), ... };
}For the second instance, the boot-time get_usage SDK probe evidently reports rate_limits_available: false (inferred from client behavior — the raw probe response body isn't logged anywhere, so I could not confirm exactly which condition on that instance triggers it; the instance uses a distinct CLAUDE_CONFIG_DIR and also has a CLAUDE_CODE_OAUTH_TOKEN environment override configured, but the reporter's actual sign-in for that instance was interactive, not token-based, so the trigger is unconfirmed). Whatever the trigger, once it fires, T3 marks the instance "unsupported" — the same bucket used for API-key accounts that genuinely have no subscription. That is silent by design in two places:
collectLimitAccounts(packages/shared/src/usageLimits.ts) skips any provider whoseusageLimitscarries a notice, including"unsupported"— no bar drawn.collectLimitNoticesexplicitlycontinues pastreason === "unsupported"— no warning shown either.
This traps the instance permanently: applyUsageLimitsUpdate (apps/server/src/provider/providerUsageLimits.ts) refuses to apply later updates once a snapshot is marked "unsupported", on the assumption "an account that cannot have subscription windows will not start reporting them mid-turn." That assumption doesn't hold here — the provider event log shows genuine mid-turn rate_limit_event data from this same instance (five_hour at 109% utilization, seven_day at 45%), proving the account does have real, trackable quota. That data is discarded on arrival because the snapshot is already locked to "unsupported".
Net effect: a second Claude account with real subscription limits is indistinguishable, in this code path, from an account with no subscription at all, and disappears from the Limits tab with zero user-facing feedback — regardless of which auth method it used to sign in.
Checked upstream issue #12170, which covers a related but distinct bug (a transient probeFailed state after a failed boot probe, which self-heals within ~5 minutes via periodic refresh). This case doesn't self-heal — every fresh probe re-derives the same "unsupported" state, so it persists indefinitely across days of use. Not a duplicate.
Steps to reproduce
- Configure a second Claude provider instance signed into a different Anthropic account than the first, using its own
homePath(separateCLAUDE_CONFIG_DIR). - Open Usage → Limits.
- Observe: only one of the two instances ever gets a bar or a notice, before or after refreshing.
- Run a turn on the instance with no bar until it hits a rate limit. The mid-turn warning carries real utilization data, but the Limits tab still shows nothing for that instance.
Version
0.0.42 (also confirmed present in the currently-running desktop build, 0.0.43-nightly.20260919.1978 — no relevant commits landed between the two)
Environment
Linux x64, Node v26.8.2, claude CLI 2.1.278
Evidence
[2026-09-20T18:58:27.751Z] CANON: {"type":"runtime.warning","provider":"claudeAgent","payload":{"message":"Claude usage limit reached. This turn is paused until the 5-hour limit resets in 2h 12m.","detail":{"status":"rejected","resetsAt":1789938600,"rateLimitType":"five_hour","overageStatus":"rejected","overageDisabledReason":"org_level_disabled","isUsingOverage":false,"unifiedWindows":{"five_hour":{"utilization":1.09,"resetsAt":1789938600},"seven_day":{"utilization":0.45,"resetsAt":1789938000}}}},"providerInstanceId":"claudeAgent_bagri"}
Related issues
#12170 — related mechanism (probeFailed → sparse window merge), but transient/self-healing, unlike this permanent "unsupported" lock. Not a duplicate.
Fix applied or workaround
None found.
Filed by
claude (sonnet-5) via t3 triage
Activity
juliusmarminge commentedon Sep 22, 2026
Triage
Verdict: Confirmed on
v0.0.42(719a76ca1) and currentmain(aff9318bf). Keep open. Not fixed by nightlies after 0.0.42 (including the cited0.0.43-nightly.20260919.1978). Not a duplicate of #12170. No later commit touchesclaudeUsageResponseToLimits/ theunsupportedlock inapplyUsageLimitsUpdate.This is a real server usage-limits bug. A second Claude instance can be permanently classified as
unsupportedafter the bootget_usageprobe, then silently omitted from Usage → Limits with no bar and no notice — even while mid-turnrate_limit_eventdata proves the account has real subscription windows.What you reported
Two Claude provider instances, separate Anthropic accounts, each with its own
homePath/CLAUDE_CONFIG_DIR. Only one ever appears under Usage → Limits. The other never gets a bar, warning, or error. Hitting a real rate limit on the missing instance surfaces utilization in a turn warning (five_hourat 109%,seven_dayat 45% forclaudeAgent_bagri), but Limits still shows nothing for it. Persists across days; refresh does not heal it.That matches the code.
What the code does
Probe →
unsupported.probeClaudeCapabilitiescalls the experimentalget_usageAPI per instance (with that instance’sCLAUDE_CONFIG_DIRfrommakeClaudeEnvironment).claudeUsageResponseToLimitscollapses both of these shapes tounavailable: { reason: "unsupported" }:So
rate_limits_available: false(API-key / Bedrock intent) andrate_limits_available: truewithrate_limits: null(transient fetch failure — the fix(claude): keep limits when the usage fetch fails #10597 shape) are indistinguishable. The raw probe body is not logged, so this report’s exact trigger is unconfirmed; either path yields the same lock.Limits UI hides
unsupportedcompletely.collectLimitAccountsskips any provider wherelimitsNotice(...) !== null. Forunsupported,limitsNoticereturns “This account has no subscription limits.”collectLimitNoticesthen explicitlycontinues pastreason === "unsupported", so that message never appears on the Limits tab either.Mid-turn data cannot recover.
applyUsageLimitsUpdatereturnspreviousunchanged whenprevious?.unavailable?.reason === "unsupported", on the assumption “an account that cannot have subscription windows will not start reporting them mid-turn.” The loggedrate_limit_event/runtime.warningforclaudeAgent_bagrifalsifies that for this instance: realfive_hour/seven_dayutilization is produced and then discarded.Re-probes re-lock.
resolveUsageLimitsAfterProbetreatsunsupportedas authoritative (it replaces published limits). Every successful probe that re-derivesunsupportedkeeps the instance buried. Unlike Claude usage limits: a rate_limit_event after a failed probe is published as a complete window list #12170’sprobeFailedpath, this does not self-heal on the 5-minute refresh.homePathisolation itself is fine (ClaudeHome.ts/ adapter tests). The bug is classification + lock + silent UI skip, not config-dir mixing.Related, not duplicates
rate_limit_eventafterprobeFailedpublished as a complete one-window listunavailablereason. This issue is a permanentunsupportedlock with no Limits row.available: true+rate_limits: null→probeFailedinstead ofunsupportedavailable: falseon a subscription account. Landing it without #12170/#12700 would also widen the sparse-merge hole.unsupported→ same silent Limits vanishNo open issue tracks “second Claude account stuck as
unsupportedand invisible on Limits.”Suggested fix
Keep this a small server (+ optional shared UI) bugfix. Do not invent a new limits protocol.
unsupportedinclaudeUsageResponseToLimits. Reserve it for accounts that can never report subscription windows (API key / Bedrock / Vertex). Maprate_limits_available: true+ missingrate_limitstoprobeFailed(the fix(claude): keep limits when the usage fetch fails #10597 distinction). If interactive OAuth / Max accounts can still returnavailable: falseunder a separateCLAUDE_CONFIG_DIR, treat that asprobeFailed(or log and investigate) rather than a permanent can-never-report mark.unsupporteddiscard mid-turn windows forever. Options (pick one, keep it small):rate_limit_eventupdates to clear / demote a mistakenunsupported(then apply the Claude usage limits: a rate_limit_event after a failed probe is published as a complete window list #12170/fix(server): keep usage-limits incomplete after sparse post-probe updates #12700 incomplete-marker rules so sparse updates do not look complete), orunsupportedas irreversible when the same instance later emits utilization events.get_usageshape (rate_limits_available, whetherrate_limitsis null) on the probe path so the next multi-instance report is not inferred.unsupported, show a notice instead of the total omit incollectLimitNotices. True API-key accounts can stay muted; subscription-looking accounts should not vanish.available:true+null→ not permanent silent omit;unsupported+ mid-turn{ id: "five_hour" }must not stay a black hole if you choose (2); existing API-key →unsupportedcase stays green.Coordinate with #12700 so a probeFailed reclassification does not reintroduce weekly-only “complete” snapshots.
Do not treat “refresh Limits,” “wait for provider health,” or landing #10597 alone as the fix.
Workaround
None that restores the Limits row while the probe keeps returning the failing shape. Mid-turn rate-limit warnings still carry real utilization for that instance. Ensuring both instances are interactively signed in under their own
homePath(and that env overrides likeCLAUDE_CODE_OAUTH_TOKENare not pointed at the wrong account) is worth checking, but this report’s evidence already shows a live subscription on the missing instance.Classification: bug · accepted · medium (server usage-limits; multi-Claude-instance; permanent
unsupportedlock; silent Limits omit; related to #12170 / #10597 / #12799)fatalist commentedon Oct 3, 2026
Hit this with a single Claude instance (no second account, no
CLAUDE_CODE_OAUTH_TOKENoverride), and I can confirm whichget_usageresponse triggers it.Setup: T3 Code (Nightly) 0.0.46-nightly.20261003.2638, Claude Code CLI 2.1.288, Claude Team subscription, macOS 27.2. Usage → Limits only shows Codex. Claude isn't there at all, and there's no notice either.
What the CLI returns: I ran the same calls the capabilities probe makes (
initializationResult()and thenusage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET()) through@anthropic-ai/claude-agent-sdkagainst the same CLI binary:{ "subscription_type": "team", "rate_limits_available": true, "rate_limits": null }I got the same result with
settingSources: [], so it isn't caused by my user settings.So the account clearly has subscription limits (
rate_limits_available: true), butrate_limitsisnull. In the 2.1.288 bundle,rate_limitsis onlynullwhen the CLI's own usage fetch doesn't come back withstatus: "ok", e.g. an in-band error, a 429, or an empty body. In other words, the fetch failed on the CLI side. It doesn't mean the account has no limits.claudeUsageResponseToLimitstreats both cases the same way:t3code/apps/server/src/provider/Layers/claudeUsageLimits.ts
Lines 162 to 167 in 8d84666
and then
collectLimitNoticesskips"unsupported"without showing anything:t3code/packages/shared/src/usageLimits.ts
Lines 302 to 304 in 8d84666
Suggestion: only use
"unsupported"whenrate_limits_available === false. When it'struebutrate_limitsisnull, treat it asprobeFailed, so the user sees a notice, laterrate_limit_events aren't locked out, and the next probe can recover.Screenshots: the composer is on Claude Opus 5, and the Limits tab shows only Codex.
fix(server): report a signed-out Claude CLI instead of hiding its limits
caitlon commentedon Oct 5, 2026
Confirmed one trigger for the silent
unsupported: a token fromclaude setup-tokenpassed throughCLAUDE_CODE_OAUTH_TOKEN.Same Claude Max account, same machine, same SDK probe T3 runs (
initializationResult()+usage_EXPERIMENTAL…()):account.subscriptionTypeget_usageCLAUDE_CODE_OAUTH_TOKENfromclaude setup-tokenrate_limits_available: false/login(credentials file, scopes includeuser:profile)Claude Maxtrue, windows presentIt shows up as soon as T3 runs on a remote machine over SSH: the macOS keychain is locked in an SSH session, so a setup token is the usual way to sign Claude in there. The Limits tab then says "No provider on the selected environments reports subscription limits", while Tokens and Cost still work, so nothing points at the token.
Telling apart "no subscription" from "signed in with an inference-only token" would make this self-explanatory: the init result already reports
tokenSource: CLAUDE_CODE_OAUTH_TOKEN, so the Limits tab could say that limits need a fullclaude /logininstead of staying silent.fix(server): report a signed-out Claude CLI instead of hiding its limits
fix(server): report a signed-out Claude CLI instead of hiding its limits
fixfon commentedon Oct 12, 2026
I'm picking this up. I reproduced it on main with a failing test:
claudeUsageResponseToLimitsmapsrate_limits_available: truewithrate_limits: nulltounsupported, which hides the account from Limits and discards streamed windows. The fix narrowsunsupportedtorate_limits_available: falseand maps thetrue+nullshape toprobeFailed, so it shows a notice and recovers on the next probe or streamed window. It is separate from #12170 / #15116 (sparserate_limit_eventhandling) and from theCLAUDE_CODE_OAUTH_TOKENsetup-token case, which really reportsrate_limits_available: false.