Usage view misreports limits with multi-account Codex routing#11515

openedSep 13, 2026byCcoygeek

Bug: Usage view reports a single Codex account when traffic is routed across multiple accounts

Summary

T3 Code’s Usage view does not represent multi-account Codex usage correctly when Codex requests are sent through a local OpenAI-compatible proxy that rotates between two ChatGPT/Codex subscriptions. The page is misleading because it presents duplicated or identical Codex limit bars while the account details do not identify or aggregate the underlying account pool.

Environment

  • Application: T3 Code (Nightly) on macOS
  • Provider shown in the client: Codex
  • Subscription setup: two separate ChatGPT/Codex Max subscriptions, referred to here as Account A and Account B
  • Routing: local CLIProxyAPI/VibeProxy account pool, using two stored Codex OAuth credentials and round-robin/session-affinity routing
  • Proxy endpoint: localhost OpenAI-compatible endpoint
  • Related setup guide: CLIProxyAPI and VibeProxy Multi Account Guide.md
  • Prior validation: the account pool was tested with fresh sessions, simultaneous requests, Codex resume, failover, and restart recovery; requests were observed using both accounts.

Steps to reproduce

  1. Configure CLIProxyAPI/VibeProxy with two eligible Codex OAuth accounts (Account A and Account B).
  2. Route Codex CLI requests from T3 Code through the local OpenAI-compatible proxy.
  3. Send requests that are distributed across both accounts.
  4. Open T3 Code → Usage → Limits.
  5. Inspect the Codex weekly limit bars and open each Codex popover.

Actual behavior

  • The Usage page shows two identical-looking Codex weekly bars with the same remaining percentage and reset time.
  • The bars do not clearly identify Account A versus Account B, nor do they show an aggregate pool total.
  • Opening a bar shows a single Codex identity/context and a single limit state. The other account’s usage is not visibly incorporated into the displayed statistics.
  • The result can be read as one account’s usage, or as a duplicated representation of one account, even though requests are being routed through both accounts.
  • In the Codex CLI, the corresponding status reports Limits: data not available yet when using the custom local provider, which gives no account-level explanation.

Expected behavior

When T3 Code is using a provider through a multi-account router, the Usage view should do one of the following:

  1. Show an explicit aggregate: combine the limits for Account A and Account B, label the result as a pooled/aggregated value, and explain how the percentage is calculated; or
  2. Show account-level limits: list each account separately with a stable anonymized/account label, its remaining percentage, reset time, and contribution to the pool; or
  3. State that limits are unavailable: if T3 Code cannot query limits for a custom provider or cannot associate usage with individual upstream accounts, say so prominently instead of rendering duplicated or misleading Codex limit bars.

The UI should also distinguish “multiple environments/sessions” from “multiple upstream accounts.” Two identical bars should not imply two independently measured accounts unless the data source confirms that.

Evidence

  • T3 Code Usage screenshots show duplicated Codex bars with the same remaining percentage and reset countdown.
  • The popovers expose only one signed-in context at a time and do not present an account-pool total or account labels.
  • The local account-pool setup uses two separate Codex credentials and has been validated with requests reaching both accounts.
  • CodexBar 0.60.0 recognizes two configured Codex accounts (the live upstream fetch was unavailable during capture because of a DNS/network error), confirming that the local setup contains two account identities rather than one.

Impact

The display can cause users to believe they have one remaining quota, two duplicate quotas, or a correctly aggregated quota when none of those interpretations is established. This makes it difficult to decide whether a limit is approaching, which account is exhausted, or whether routing is working as intended.

Suggested fix

Detect custom-provider/multi-account routing where possible. If account attribution is unavailable, replace the current duplicated Codex bars with an explicit “limit data unavailable for this provider” state and link to the provider/configuration details. If attribution is available, render a per-account breakdown plus a clearly labeled aggregate rather than duplicating one account’s result.

Triage

This is a real Usage → Limits attribution bug in a setup we already model, not a missing multi-account product.

T3 does not infer upstream ChatGPT accounts from an OpenAI-compatible proxy. Request routing and limit reads are separate:

  • Codex usage on the provider comes from the local CLI’s account/rateLimits/read (CodexProvider / codexUsageLimits). A custom/local provider is exactly the case where Codex itself reports Limits: data not available yet.
  • Per-account pool data comes from a CLIProxyAPI Usage hub: Settings → Providers → Usage providers → Add hub. That path (UsageLimitSources + cliproxyApi) reads each stored OAuth file and is documented in Usage and limits. Routing Codex through the proxy does not turn those files into Usage rows by itself.

The Limits UI already pools by provider (collectLimitAccounts / collectLimitPools in packages/shared/src/usageLimits.ts; web UsageLimitsPooled, same collectors on mobile). Identity is driver + email. Instances without an email stay separate (environmentId:instanceId). Two identical weekly segments with the same remaining % and reset are therefore almost certainly the same native/cached ChatGPT snapshot drawn twice (two Codex instances and/or two selected environments), not independently measured Account A vs Account B. The popover showing one Codex identity matches that: it is one LimitAccount, not a pool total.

That matches the open cluster:

  • #10877 (approved) — stop publishing native quota for custom Codex (requiresOpenaiAuth: false); this is the “say limits are unavailable” outcome you asked for.
  • #11473 / #11467 — CLIProxy can still leak cached ChatGPT limits as extra native accounts.
  • #10701 / #10700 — /usage-limits double-counts the same subscription (composer command; Limits page already merges when email matches).
  • #10835 / #10845 / #10876 — real same-email / workspace split, only if the two bars are actually different subscriptions.

We are not going to auto-detect a proxy account pool from the OpenAI-compatible endpoint. If attribution is missing, the bars should go away (unsupported / unavailable), not look like two measured accounts.

Workaround today: add the hub under Usage providers (management URL + key), then use those rows as the source of truth. Treat native Codex bars on a custom provider as untrusted.

Please confirm (so we know whether this is only the custom-provider leak or also a failed hub read):

  1. Is a hub configured at Settings → Providers → Usage providers?
  2. How many Codex provider instances, and how many environments are selected on Usage?
  3. In each weekly popover: display name, plan, Signed in vs Via, and whether the emails differ.

No further design work needed beyond landing #10877 / #11473 and, if a hub is already configured and the bars still match after that, checking the collector identity for that snapshot.

Synced from GitHub

I'm picking this up. I reproduced the custom-provider leak with a failing test on main: a Codex instance with requiresOpenaiAuth: false still publishes the stored ChatGPT login's account/rateLimits/read answer as native quota. I'll follow the triage direction only, so custom Codex providers report limits as unavailable instead, with no changes to multi-account routing or identity matching. PR to follow shortly.

Synced from GitHub

Keeping this open. I checked main at 96bae5465bc5dfaedc890998a7a71672fb470ae2 and stable v0.1.1: the native-quota guard still excludes only API-key accounts. A pure-code probe confirms that requiresOpenaiAuth: false with a null or stored ChatGPT account can still publish cached weekly limits, and two email-less environments remain separate rows. #10877 and #11473 closed without merging; #18622 is still open. This was source/pure-code verification, not a live proxy or UI retest. The accepted custom-provider attribution bug is not yet resolved.

Synced from GitHub

Seeing this too on Nightly (macOS), with one ChatGPT account.

Setup: Codex CLI uses a CLIProxyAPI hub as a custom provider (model_provider = "cliproxy", requires_openai_auth = false), and the same hub is added under Usage providers. The hub holds a single Codex login.

Usage → Limits → All environments shows four Codex weekly bars with the same remaining % and reset time: three unlabeled native "Codex" segments (one per environment) plus the hub's row, which has the account's initials. Claude logins in the same setup merge correctly.

Confirmed locally: codex app-server returns account/read → {"account": null, "requiresOpenaiAuth": false}, while account/rateLimits/read still returns the stored ChatGPT login's limits. So each environment publishes an email-less native row that can't merge with the others or with the hub row, as described in the triage above. Dropping native quota for custom providers (#18622) would leave just the hub row, which is what we'd want.

Synced from GitHub

I'm seeing a similar issue with two ChatGPT accounts: one work account and one personal account. Both are connected directly in T3 Code through ChatGPT authentication, but Usage → Limits shows usage for only one of them. This setup does not use the multi-account proxy described in the original report, so it may be a separate cause.