Repository navigation
Description
fix(ai): Command Code quota monthly window vanishes when remaining credits exceed the hard-coded 10 included — an over-limit payload reads as "could not be parsed"
Verified 2026-11-05 on origin/main fba8bcca0b (laptop primary, clean), probe at ~/git/fleet/probe-2026-11-05-creator-opencode-0815/probe.ts on the laptop (bun, run against the real parser).
The bug
packages/ai/src/quota/providers/command-code.ts:62-72 — parseCommandCodeCredits only publishes the monthly window when the remaining balance falls inside the assumed included range:
export const MONTHLY_INCLUDED_CREDITS = 10
const monthlyRemaining = toNumber(credits?.monthlyCredits)
if (monthlyRemaining !== null && monthlyRemaining >= 0 && monthlyRemaining <= MONTHLY_INCLUDED_CREDITS) {
const monthlyUsed = MONTHLY_INCLUDED_CREDITS - monthlyRemaining
windows.monthly = toUsageWindow({ usedPercent: ..., valueLabel: `${monthlyUsed} / 10`, ... })
}Any remaining balance above the hard-coded 10 (a plan change, a promo/rollover grant, a higher included tier, an upstream field whose meaning is total rather than remaining) drops the window entirely — no window, no error, no clamp.
Reproduced (probe, payload-shaped, against the real parser)
parseCommandCodeCredits({ credits: { monthlyCredits: 5 } })→monthlywindow,usedPercent: 50, label"5 / 10"✓parseCommandCodeCredits({ credits: { monthlyCredits: 10 } })→monthlywindow,usedPercent: 0✓parseCommandCodeCredits({ credits: { monthlyCredits: 25 } })→{}— no windows at allparseCommandCodeCredits({ credits: { monthlyCredits: 25 }, windowLimits: { fiveHour: { used: 1, cap: 4, resetAt: 1893456000 } } })→ only the5hwindow; monthly silently absent- Downstream: when the monthly credit is the only data in the payload,
fetchCommandCodeUsage(command-code.ts) throws"Command Code usage data could not be parsed"on a perfectly parseable payload, and the provider reports a hard failure instead of a healthy 0%-used month.
Why it matters
This is the same failure shape the repo just fixed for Turso in #1743 ("publish over-limit windows above 100 percent", merged PR #1743): a value outside the assumed range must be published truthfully (here: 0% used, with the real remaining figure visible), never dropped. A dropped monthly window reads downstream as "no quota data" — the opencode quota display loses the provider's headline window and quota-aware consumers reason from an absence. The hard-coded MONTHLY_INCLUDED_CREDITS = 10 makes the trigger more likely over time, not less: the first plan that includes more than 10 monthly credits breaks the read.
Negative remaining (monthlyCredits: -3) also drops the window in the probe; that is nonsense data and dropping it is defensible — the acceptance below only requires the over-included case to publish.
Acceptance criteria
-
parseCommandCodeCreditswithmonthlyCreditsaboveMONTHLY_INCLUDED_CREDITSpublishes amonthlywindow withusedPercent: 0and a value label that shows the real remaining figure (not a fabricated "0 / 10" that hides it). - In-range behavior is unchanged: 5 → 50% used, label "5 / 10"; 10 → 0% used.
- A payload whose only data is an over-included monthly credit no longer makes
fetchCommandCodeUsagethrow "could not be parsed". - Tests in
packages/ai/test/quota.test.ts(or a wired sibling) pin the over-included case alongside the in-range cases. - Existing quota tests still pass under the ai package test command; ai typecheck clean.
Activity
dezren39 commentedon Nov 5, 2026
Filed this run by the issue creator after a laptop probe against the real parser confirmed the over-included monthly window drops (and a monthly-only payload then reads as 'could not be parsed').
Found via: filed this run
dezren39 commentedon Nov 5, 2026
Self-assigned for a guarded trivial fix this run (lifecycle protocol §4): one guard change in parseCommandCodeCredits plus pinning tests, verified on the laptop.
Merge pull request #1745 from developing-today-forks/creator/1744-com…
dezren39 commentedon Nov 5, 2026
Self-solved this run: PR #1745 merged (b2459a4). Laptop verification: quota tests 13 pass / 58 expects, negative control 1 fail, ai typecheck clean.
Merge pull request #2117 from developing-today-forks/queue/12901-1934…