[BUG] Desktop usage widget mixes two token units: cached days count cache tokens, live days don't, so models first used after lastComputedDate vanish from the Models tab

Status Fixed / completed
Reported on v2.1.281
Maintainer reply None cached
Activity 0 comments · opened Sep 25, 2026 · closed Sep 25, 2026

What's Wrong?

The Code tab usage widget in Claude Desktop (Overview / Models, "All") merges days from ~/.claude/stats-cache.json with days it recomputes live from transcripts. The two halves use different definitions of "tokens":

  • Cached days (dailyModelTokens, written by the CLI's Stats screen, dailyModelTokensVersion: 5) count input + output + cache_read + cache_creation.
  • Live days (after lastComputedDate, computed by the desktop stats worker) count only input + output:

``js
// app.asar, codeStats worker (minified)
let i = t.inputTokens + t.outputTokens;
if (i > 0) { let t = l.get(n) ?? Object.create(null); t[e] = (t[e] ?? 0) + i; l.set(n, t) }
``

For agentic use the difference is two to three orders of magnitude. The renderer then sums dailyModelTokens for "Total tokens" and hides any model below 0.05% of that total (p = f * 5e-4; m = d.filter(e => e.tokens >= p)). A model that only appears after lastComputedDate is measured in the small unit against a total measured in the big one, so it drops under the cutoff and disappears from the Models tab. Its tokens are also effectively missing from "Total tokens".

Because only the CLI writes the cache (#87772), this happens to anyone who uses the desktop app and rarely opens the CLI Stats screen. For me it hid a newly released model completely.

Measured on my machine

Cache lastComputedDate = 2026-09-22. Claude Opus 5.5 was first used on 2026-09-23.

| | value |
|---|---|
| One cached day (2026-09-22, claude-opus-5) in cache | 331,145,685 |
| Same day recomputed from transcripts, all four token types | 331,145,685 (exact match) |
| Same day, input + output only | 905,388 |
| Sum of cached dailyModelTokens = widget "Total tokens" | 32,196,738,130 (shown as 32.2B) |
| claude-opus-5-5, live days, input + output (desktop's unit) | 4,398,793 (0.014% of total → hidden, cutoff is 0.05%) |
| claude-opus-5-5 after running CLI Stats (cache now through 2026-09-24, CLI's unit) | 1,541,603,954 (4.53% → shown) |

I verified the desktop numbers by running the codeStats worker function extracted verbatim from app.asar against the same ~/.claude directory.

What Should Happen?

Cached and live days should use the same unit, so the widget does not depend on when the CLI last wrote the cache. Either the desktop worker adds all four token types for live days (matching the CLI's dailyModelTokensVersion 5), or the renderer uses a unit that both sides share.

Steps to Reproduce

  1. Have a stats-cache.json written by the CLI Stats screen (so dailyModelTokens includes cache tokens).
  2. Only use the desktop app for a few days, and use a model that does not appear in the cache (for example a newly released one).
  3. Open the Code tab home screen → usage widget → Models → All. The new model is missing, and "Total tokens" equals the sum of the cached dailyModelTokens.
  4. Move stats-cache.json away and reload: the model appears, because now every day is computed in the input + output unit.
  5. Or run claude → /stats in a terminal instead: the model appears, because the CLI rewrote those days in the cache-inclusive unit. Today's usage is still added in the smaller unit.

Related

  • #87772: only the CLI writes the stats cache (the reason the live window grows)
  • #85509: "Total tokens" in the desktop widget is summed from dailyModelTokens

Environment

  • Claude Desktop 2.9939.2 (macOS 27.0)
  • Claude Code CLI 2.1.281
  • stats-cache.json version 5, dailyModelTokensVersion 5

View original on GitHub ↗