MoonshotAI / MoonshotAI/kimi-code
fix(oauth): extraUsage always null — parseManagedUsagePayload reads "boosterWallet" but /usages returns "booster_wallet"
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.5k
- Forks
- 1.2k
- Avg merge
- 11h 53m
- Merged PRs (30d)
- 350
Description
Bug
GET https://api.kimi.com/coding/v1/usages returns the booster wallet under the
snake_case key booster_wallet, but parseManagedUsagePayload reads the camelCase
key boosterWallet. As a result, quota.extraUsage is always null in
production, even for accounts with an active booster wallet and remaining balance.
Introduced by #3787 (bb0c66a1, released in 0.43.0), still present on latest main.
Evidence
Live response from GET /usages (2026-09-16, redacted):
{
"usages": { "limit_5h": {}, "limit_7d": {} },
"booster_wallet": {
"balance": { "type": "BOOSTER", "amount": "20000000000",
"amountLeft": "10336703900", "unit": "UNIT_CURRENCY" },
"status": "STATUS_ACTIVE",
"monthlyUsed": { "currency": "CNY", "priceInCents": "9663" }
}
}
But packages/oauth/src/managed-usage.ts:
return {
usages: parseQuotaUsages(payload['usages']),
extraUsage: parseBoosterWallet(payload['boosterWallet']), // <- never matches
};
Note the sibling usages parsing correctly uses snake_case (limit_5h,
limit_7d, used_ratio, reset_time) — only the booster wallet key is camelCase.
Why the tests did not catch it
packages/oauth/test/managed-usage.test.tsfeedsparseManagedUsagePayloada
fixture with the camelCase keyboosterWallet, matching the buggy reader instead
of the real server payload.- The
fetchManagedUsagetest's mocked/usagesresponse contains no booster
wallet at all, so the wire format is never exercised end-to-end.
Impact
- Local server
/api/v1/oauth/usagealways returnsquota.extraUsage: null. - The booster section in the web settings UI (
PlanUsageCard,settings.planUsage.boosterTitle)
never renders, so users cannot see their booster balance anywhere.
Suggested fix
extraUsage: parseBoosterWallet(payload['booster_wallet'] ?? payload['boosterWallet']),
(reading both keys keeps compatibility if the gateway ever normalizes to camelCase),
and update the test fixture to use the real snake_case wire format, plus add a
booster_wallet entry to the fetchManagedUsage mock response.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/oauth/src/managed-usage.ts and read packages/oauth/test/managed-usage.test.ts, especially the parseManagedUsagePayload fixture and fetchManagedUsage mock. Run the managed-usage tests, then verify that the real snake_case booster_wallet response produces quota.extraUsage and that the end-to-end mock covers the booster wallet.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100