jackwener/OpenCLI · error · CommandExecutionError

kimi usage returned malformed payload: missing or invalid "$

Error message

kimi usage returned malformed payload: missing or invalid "${name}"

What it means

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.

Source

Thrown at clis/kimi/usage.js:32

    if (r.width < 1 || r.height < 1) return false;
    const cs = getComputedStyle(el);
    if (cs.visibility === 'hidden' || cs.display === 'none' || cs.opacity === '0') return false;
    return true;
  };
`;

function parsePct(value) {
    const m = String(value || '').match(/(\d+(?:\.\d+)?)\s*%/);
    return m ? Number(m[1]) : null;
}

function normalize(s) {
    return String(s || '').trim();
}

function requireFinite(value, name) {
    if (!Number.isFinite(value)) {
        throw new CommandExecutionError(`kimi usage returned malformed payload: missing or invalid "${name}"`);
    }
    return value;
}

function requireText(value, name) {
    const text = normalize(value);
    if (!text) {
        throw new CommandExecutionError(`kimi usage returned malformed payload: missing "${name}"`);
    }
    return text;
}

cli({
    site: 'kimi',
    name: 'usage',
    access: 'read',
    description: 'Read Kimi membership quota usage from the subscription page: total usage, rate limits, gift quota, and booster balance.',
    domain: KIMI_DOMAIN,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry — a transient/truncated payload is often the cause.
  2. Log in again so the usage endpoint returns complete data.
  3. Update the library to match Kimi's current usage payload shape.
  4. Inspect the raw usage response to see which field is missing and file/patch a parser fix.

Example fix

// before
const used = requireFinite(Number(data.used), 'used'); // throws on '--'
// after
const rawUsed = String(data.used).replace(/[^0-9.]/g, '');
const used = requireFinite(Number(rawUsed), 'used');
Defensive patterns

Strategy: type-guard

Validate before calling

const nums = ['used','limit','remaining'];
for (const k of nums) {
  const v = Number(payload?.[k]);
  if (!Number.isFinite(v)) throw new Error(`usage payload field "${k}" is not finite before calling kimi usage`);
}

Type guard

const isFiniteNumber = (v) => typeof v === 'number' && Number.isFinite(v);

Try / catch

try {
  const usage = await run('kimi', 'usage');
} catch (e) {
  if (/malformed payload/.test(e.message)) {
    await page.reload();
    return run('kimi', 'usage'); // retry once on transient/truncated payload
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/f8099a2894f6590a. Report an issue: GitHub.