{"record":{"id":"f8099a2894f6590a","repo":"jackwener/OpenCLI","slug":"kimi-usage-returned-malformed-payload-missing-or","errorCode":null,"errorMessage":"kimi usage returned malformed payload: missing or invalid \"${name}\"","messagePattern":"kimi usage returned malformed payload: missing or invalid \"(.+?)\"","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/kimi/usage.js","lineNumber":32,"sourceCode":"    if (r.width < 1 || r.height < 1) return false;\n    const cs = getComputedStyle(el);\n    if (cs.visibility === 'hidden' || cs.display === 'none' || cs.opacity === '0') return false;\n    return true;\n  };\n`;\n\nfunction parsePct(value) {\n    const m = String(value || '').match(/(\\d+(?:\\.\\d+)?)\\s*%/);\n    return m ? Number(m[1]) : null;\n}\n\nfunction normalize(s) {\n    return String(s || '').trim();\n}\n\nfunction requireFinite(value, name) {\n    if (!Number.isFinite(value)) {\n        throw new CommandExecutionError(`kimi usage returned malformed payload: missing or invalid \"${name}\"`);\n    }\n    return value;\n}\n\nfunction requireText(value, name) {\n    const text = normalize(value);\n    if (!text) {\n        throw new CommandExecutionError(`kimi usage returned malformed payload: missing \"${name}\"`);\n    }\n    return text;\n}\n\ncli({\n    site: 'kimi',\n    name: 'usage',\n    access: 'read',\n    description: 'Read Kimi membership quota usage from the subscription page: total usage, rate limits, gift quota, and booster balance.',\n    domain: KIMI_DOMAIN,","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/kimi/usage.js#L14-L50","documentation":"requireFinite in clis/kimi/usage.js validates numeric fields parsed from Kimi's usage payload. If a value is not a finite number (undefined, NaN, Infinity, or a non-numeric string coerced badly), it throws CommandExecutionError saying the payload is missing or invalid for that field name. This guards downstream math/formatting from NaN quotas.","triggerScenarios":"Calling the kimi usage command when Kimi's usage endpoint/page returns a payload where a numeric field (e.g. used, limit, remaining) is absent, null, a string like '--', or NaN.","commonSituations":"Kimi changed the usage page/endpoint shape; account state (new or flagged) omits quota fields; scraping returned placeholder text instead of numbers; partial outage returning truncated JSON.","solutions":["Retry — a transient/truncated payload is often the cause.","Log in again so the usage endpoint returns complete data.","Update the library to match Kimi's current usage payload shape.","Inspect the raw usage response to see which field is missing and file/patch a parser fix."],"exampleFix":"// before\nconst used = requireFinite(Number(data.used), 'used'); // throws on '--'\n// after\nconst rawUsed = String(data.used).replace(/[^0-9.]/g, '');\nconst used = requireFinite(Number(rawUsed), 'used');","handlingStrategy":"type-guard","validationCode":"const nums = ['used','limit','remaining'];\nfor (const k of nums) {\n  const v = Number(payload?.[k]);\n  if (!Number.isFinite(v)) throw new Error(`usage payload field \"${k}\" is not finite before calling kimi usage`);\n}","typeGuard":"const isFiniteNumber = (v) => typeof v === 'number' && Number.isFinite(v);","tryCatchPattern":"try {\n  const usage = await run('kimi', 'usage');\n} catch (e) {\n  if (/malformed payload/.test(e.message)) {\n    await page.reload();\n    return run('kimi', 'usage'); // retry once on transient/truncated payload\n  }\n  throw e;\n}","preventionTips":["Validate raw scraped values with Number.isFinite before numeric processing.","Keep the usage parser in sync with Kimi's payload changes.","Retry once on malformed payloads — they are often transient."],"tags":["payload-validation","usage","kimi"],"backgroundTag":"malformed-api-payload","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}