jackwener/OpenCLI · error · CommandExecutionError

Bilibili ${label} API returned a malformed payload

Error message

Bilibili ${label} API returned a malformed payload

What it means

requireOkPayload() validates the raw JSON returned by a Bilibili API endpoint (used by viewData and conclusionData). If the body is not a non-array object — null, a string, an array, or unparseable output — it throws this CommandExecutionError because the response shape cannot even carry a code/message envelope. This signals an unexpected/changed API response rather than a logical API error.

Source

Thrown at clis/bilibili/summary.js:60

            if (!match) {
                throw new ArgumentError('Bilibili summary URL must contain a BV video id');
            }
            return match[1];
        }
        if (!B23_HOST_RE.test(parsed.hostname)) {
            throw new ArgumentError('Bilibili summary URL must be a bilibili.com or b23.tv URL');
        }
    }
    try {
        return await resolveBvid(input);
    } catch (error) {
        throw new ArgumentError(`Cannot resolve Bilibili BV ID from input: ${input}`, error instanceof Error ? error.message : String(error));
    }
}

function requireOkPayload(payload, label) {
    if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
        throw new CommandExecutionError(`Bilibili ${label} API returned a malformed payload`);
    }
    if (payload.code !== 0) {
        const message = payload.message ?? 'unknown error';
        if (payload.code === -101 || payload.code === -403 || /登录|权限|forbidden|permission|login/i.test(String(message))) {
            throw new AuthRequiredError('bilibili.com', `Bilibili ${label} API requires login or permission: ${message} (${payload.code})`);
        }
        throw new CommandExecutionError(`Bilibili ${label} API failed: ${message} (${payload.code})`);
    }
    return payload.data;
}

function readModelResult(data, bvid) {
    if (!data || typeof data !== 'object' || Array.isArray(data)) {
        throw new CommandExecutionError('Bilibili conclusion API returned malformed data');
    }
    if (data.code !== 0) {
        throw new EmptyResultError('bilibili summary', `Bilibili has not generated an AI summary for ${bvid}.`);
    }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry later or from a different network — the response is likely an anti-bot page or transient gateway error.
  2. Send cookies/credentials expected by the web-interface endpoint if requests are being challenged.
  3. Check whether the API response shape changed and update the CLI/parsing code.
  4. Log the raw response body to confirm what was actually returned.

Example fix

// before
const payload = await res.json(); // HTML body throws inside json() or yields junk
// after
const text = await res.text();
let payload;
try { payload = JSON.parse(text); } catch { payload = null; }
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
  throw new Error(`Unexpected response: ${text.slice(0, 200)}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

const text = await res.text();
if (!text.trim().startsWith('{')) throw new Error(`Non-JSON response (likely anti-bot page): ${text.slice(0, 120)}`);

Type guard

function isApiEnvelope(x) {
  return x !== null && typeof x === 'object' && !Array.isArray(x) && typeof x.code === 'number';
}

Try / catch

try {
  const rows = await summaryCommand(bvid);
} catch (e) {
  if (/malformed payload/.test(e.message)) {
    // anti-bot page or API contract change: back off and retry, or inspect raw body
    await sleep(2000);
    return retrySummary(bvid);
  }
  throw e;
}

Prevention

When it happens

Trigger: The Bilibili endpoint returns an empty body, an HTML error/anti-bot page parsed as garbage, a JSON array, or null because an HTTP layer already swallowed a non-JSON response; payload.code is absent and the object check at summary.js:59-61 fires first.

Common situations: Bilibili risk-control (风控) returning an HTML challenge instead of JSON; CDN/proxy intercepting the request; API contract change after a Bilibili update; a corporate proxy returning its own error page.

Understand the failure class

Related errors


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