[Bug]: Limits merges Claude instances with different logins into one row when they share a config directory#30602
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
packages/contracts or packages/shared
Steps to reproduce
- Sign in to Claude Code with account A as usual (
claude auth login). - Sign in account B into its own login folder. Claude Code's
CLAUDE_SECURESTORAGE_CONFIG_DIRmoves only the credentials file, and~/.claudeand~/.claude.jsonstay shared:1 $env:CLAUDE_SECURESTORAGE_CONFIG_DIR = "$HOME\.claude-b" 2 claude auth login - In Settings → Providers, add a Claude instance named "Claude B". Leave its config directory empty, and add the environment variable
CLAUDE_SECURESTORAGE_CONFIG_DIRset to the full path of that folder. - Send a message on each instance so the two accounts are at different usage.
- Open Usage → Limits and click Refresh limits a few times.
I use this setup because T3 only lets a thread switch between Claude instances that use the same config directory (providers-claude.md). With it, a thread can move to another account, and CLAUDE.md, memory, and sessions stay shared.
Expected behavior
Two Claude rows, one per login, each with its own session and weekly numbers. The thread details card already shows the right numbers for a thread on each instance.
Actual behavior
There's one Claude row. It's labeled with the email stored in the shared ~/.claude.json, which belongs to whichever account signed in last. Its numbers come from whichever instance T3 checked most recently, so they switch between the two accounts. The provider cards also show the same email for every instance.
Each instance's numbers are correct. Its probe runs with its own login, and the thread details card (ThreadDetailsUsage, which looks up by instanceId) shows them right. The rows are merged because:
- Claude Code reports
account.emailfromoauthAccount.emailAddressin the shared~/.claude.json, not from the login it's using, so every instance on the machine reports the same email. - The Claude driver reads
workspaceIdfromoauthAccount.organizationUuidin the same file (readClaudeOrganizationIdinClaudeDriver.ts), so that matches too. accountKeyandcollectLimitAccountsinpackages/shared/src/usageLimits.tskey accounts by driver, email, and workspaceId, and keep the fresher reading.
Possible fix: also key a Claude instance by where its login is stored, for example by adding the instance's resolved CLAUDE_SECURESTORAGE_CONFIG_DIR to the key when it sets one. Instances that share one login, like presets, would still merge, and instances with separate logins would get their own rows.
Related: #28142 has the same symptom for hub accounts that really share an email. Its fix (#28290) only covers hub accounts.
Impact
Major degradation or frequent failure
Version or commit
0.1.6 (desktop). The same code is unchanged on main @ df2dfde.
Environment
Windows 10 22H2, T3 Code desktop 0.1.6, Claude Code 2.1.316
Logs or stack traces
| 1 |
Screenshots, recordings, or supporting files
No response
Workaround
Deleting oauthAccount.emailAddress from ~/.claude.json makes Limits fall back to one row per instance. Claude Code writes the email back (daily profile refresh, token renewals, and sign-ins), so it has to be removed again each time.