jackwener/OpenCLI · error · CommandExecutionError

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

Error message

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

What it means

requireText in clis/kimi/usage.js validates string fields from Kimi's usage payload. After trim/normalize, if the value is empty (undefined, null, or whitespace), it throws CommandExecutionError saying the payload is missing that field. It ensures reported usage rows always carry non-empty values for textual fields like model name or plan name.

Source

Thrown at clis/kimi/usage.js:40

    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,
    strategy: Strategy.COOKIE,
    browser: true,
    siteSession: 'persistent',
    navigateBefore: true,
    args: [],
    columns: [
        'membershipName',
        'membershipValidUntil',

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry — intermittent rendering can leave text nodes empty.
  2. Log in again / ensure the account has an active plan so all fields are present.
  3. Update the library's usage parser to Kimi's current markup/endpoint.
  4. Inspect the raw payload to identify the empty field and adjust extraction.

Example fix

// before
const plan = requireText(data.plan, 'plan'); // throws when ''
// after
const plan = requireText(data.plan || data.planName || 'unknown', 'plan');
Defensive patterns

Strategy: type-guard

Validate before calling

for (const k of ['plan','model']) {
  if (!String(payload?.[k] ?? '').trim()) throw new Error(`usage payload field "${k}" is empty`);
}

Type guard

const isNonEmptyText = (v) => typeof v === 'string' && v.trim().length > 0;

Try / catch

try {
  const usage = await run('kimi', 'usage');
} catch (e) {
  if (/malformed payload: missing/.test(e.message)) {
    const field = e.message.match(/missing "(.+)"/)?.[1];
    console.warn(`Kimi usage lacks field ${field}; continuing with defaults`);
    return null; // fallback path
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling the kimi usage command when a textual field (e.g. plan, model, period label) is absent or empty string in Kimi's usage payload.

Common situations: Kimi renamed/moved a label in the usage UI; account without an assigned plan so the field is blank; selector matched the wrong node yielding empty text; i18n change moved the text elsewhere.

Understand the failure class

Related errors


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