Repository navigation
[Bug]: Usage page misses Codex usage from provider instances with a custom CODEX_HOME #5805
Description
Activity
- changed the title
[-]Usage page shows no Codex usage when Codex is configured through provider instances[/-][+][Bug]: Usage page shows no Codex usage when Codex is configured through provider instances[/+]on Aug 9, 2026 - changed the title
[-][Bug]: Usage page shows no Codex usage when Codex is configured through provider instances[/-][+][Bug]: Usage page misses Codex usage from provider instances with a custom CODEX_HOME[/+]on Aug 9, 2026 I reproduced a stronger variant of this on Linux with
t3@0.0.33-nightly.20260809.1042: the Usage page settles at $0.00 / 0 processed tokens for every provider, even though both Codex and Claude have substantial recent transcript history.Environment that exposes it
The T3 server is intentionally launched with separate workspace and provider homes:
Environment=HOME=/srv/projects Environment=CODEX_HOME=/root/.codex ExecStart=t3 serve --base-dir /root/.local/share/t3code /srv/projects
This is useful for a remote server:
HOME=/srv/projectsmakes the project picker open at the workspace root, whileCODEX_HOME=/root/.codexkeeps the Codex state/auth location explicit.The persisted settings have no legacy
providersobject. Claude is configured throughproviderInstanceswith a customconfig.homePath. Codex uses the process-levelCODEX_HOME.Observed resolution
The shipped
UsageService.resolveTranscriptDirsreads:settings.providers.claudeAgent settings.providers.codex
It does not enumerate
settings.providerInstances.For Codex, the empty legacy config reaches
resolveCodexHomeLayout, whose default is based onNodeOS.homedir(). In this process:os.homedir() = /srv/projects CODEX_HOME = /root/.codexThe usage scan consequently resolves these nonexistent roots:
/srv/projects/.codex/sessions /srv/projects/.claude/projects /srv/projects/projectsThe real roots are:
/root/.codex/sessions <configured Claude provider instance home>/projectsSo this is not limited to an explicitly configured custom Codex instance: setting
CODEX_HOMEindependently ofHOMEis enough to lose all Codex usage. Reading only the legacy provider blob also loses Claude usage configured by the currentproviderInstancesmodel.Evidence that the transcripts are valid
For the same 30-day window shown in the UI, a read-only reproduction of the parsing rules shipped in
.1042found:Provider Transcript files with in-window records Parsed records Parser-compatible tokens Codex 83 12,311 1,477,313,596 Claude 31 2,802 421,490,501 These figures are only intended to prove that compatible, nonzero records exist; they are not asserted as billing totals (and Codex fork accounting is separately covered by #5758).
The live
server.getUsageSummarycalls complete successfully. There is no server-side read failure: the service returns an empty summary because both resolved roots are missing. That explains why the settled UI confidently renders zeros instead of an error. A transient reconnect can separately flash the generic “environment could not report usage” message, but it is not the cause of the persistent zero result.Expected behavior
Usage collection should use the same effective provider-home resolution as provider execution:
- Enumerate enabled
providerInstancesfor Claude and Codex, rather than reading onlysettings.providers.<kind>. - For an implicit/default Codex configuration with a blank
homePath, honorCODEX_HOMEbefore falling back tohomedir()/.codex. - Scan distinct physical transcript roots once if multiple instances share a home or a Codex auth overlay.
- Preserve per-source status so a missing configured root is visible rather than silently appearing as genuine zero usage.
Suggested regression coverage
HOME !== CODEX_HOME, with no explicitproviderInstances.codexentry.- Claude configured only through
providerInstances.<id>.config.homePath. - Multiple instances with different transcript homes.
- Multiple instances resolving to the same shared transcript directory (no double count).
- Both resolved roots missing: response sources identify them as missing and the UI does not present the result as a trustworthy zero.
This reproduction confirms the cause described in the issue and shows that it affects the standard process-level
CODEX_HOMEpath as well as custom instance homes.- Enumerate enabled
Reproduced with T3 Code
0.0.34-nightly.20260824.1173on Windows 11 x64 using the desktop app. The incorrect result is identical on desktop, web, and mobile.Two enabled
claudeAgentprovider instances use separateCLAUDE_CONFIG_DIRpaths:~/.claude-workand~/.claude-personal. Theirprojectsdirectories contain 28 and 166.jsonltranscripts respectively, but neither appears in Usage.server.getUsageSummaryandUsageService.resolveTranscriptDirscomplete successfully; this is not a scan error. In the installed source,UsageService.resolveTranscriptDirsstill resolves Claude exclusively fromsettings.providers.claudeAgent, ignoring both enabled entries insettings.providerInstances.Current
mainhas the same implementation, so the issue does not appear fixed in a newer build.Confirmed by Codex (GPT-5) via
t3 triage.Closing as fixed by #11485 — usage now follows each configured Codex/Claude/Grok account home (including custom
CODEX_HOME/CLAUDE_CONFIG_DIR).
Description
The usage page reports Claude Code usage only, even with heavy daily Codex use, when Codex is configured through
providerInstances(multiple instances, each with its ownCODEX_HOME/ shadow home) rather than the legacy single-instance settings field.Reproduction
providerInstanceswith a customCODEX_HOME(the legacyproviders.codexfield stays empty, which is what the settings UI produces for instance-based setups).sessionsdirectory.Version or commit
Reproduced on
main @ 963ebf5b(screenshot above is from that commit); also present in the current nightly.Impact
Minor in the scheme of things — the usage page is brand new and this only matters for multi-instance setups. Within that scope the numbers are silently wrong (a whole provider omitted, no error shown), which seemed worth reporting before the page reaches a wider audience.
Cause
UsageService.resolveTranscriptDirsresolves transcript directories only from the legacysettings.providers.<kind>blobs. For instance-based setups that blob decodes to defaults, so the scan reads~/.codex/sessionsonly. Instances that use the default home still show up; any instance whose home differs from the default (customCODEX_HOME, shadow home on a custom shared home) is never scanned.I have a fix ready and will attach a PR.