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
- Retry later or from a different network — the response is likely an anti-bot page or transient gateway error.
- Send cookies/credentials expected by the web-interface endpoint if requests are being challenged.
- Check whether the API response shape changed and update the CLI/parsing code.
- 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
- Send a browser-like User-Agent and valid cookies to avoid risk-control HTML pages.
- Rate-limit batch requests to Bilibili endpoints.
- Log raw response bodies on failure to diagnose intercepted responses.
- Keep the CLI updated for API contract changes.
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- ${label} returned a malformed envelope
- 12306 queryByTrainNo returned non-JSON body
- 12306 ${endpoint} returned non-JSON body
- Failed to parse 12306 station_name.js: source string not fou
- 请先在共享 Chrome 完成 1688 登录/验证,再重试(${action})
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a8e4501118f9710d.
Report an issue: GitHub.