jackwener/OpenCLI · error · CommandExecutionError
获取视频分P信息失败: ${payload?.message ?? 'unknown'} (${payload?.cod
Error message
获取视频分P信息失败: ${payload?.message ?? 'unknown'} (${payload?.code ?? 'malformed'}) What it means
loadSelectedPart calls the Bilibili web-interface/view API to fetch video metadata (including pages/分P list). After the HTTP call succeeds, it validates that the response is an object with code===0; anything else (error payload, non-zero code, non-object body) is rethrown as a CommandExecutionError embedding the API message and code. This distinguishes API-level rejection from transport errors, which are thrown by the preceding catch.
Source
Thrown at clis/bilibili/download.js:91
}
throw new CliError(
'PAID_CONTENT',
`该视频为付费内容(${PAYMENT_LABELS[paymentType]}),当前账号无观看权益,无法获取完整视频流`,
'若已购买/已充电/已开通会员,加 --force 跳过本检查直接下载',
EXIT_CODES.NOPERM,
);
}
async function loadSelectedPart(page, bvid, pageNum) {
let payload;
try {
payload = await apiGet(page, '/x/web-interface/view', { params: { bvid } });
}
catch (error) {
throw new CommandExecutionError(`获取视频分P信息失败: ${error?.message || error}`);
}
if (!isObject(payload) || payload.code !== 0) {
throw new CommandExecutionError(`获取视频分P信息失败: ${payload?.message ?? 'unknown'} (${payload?.code ?? 'malformed'})`);
}
return selectVideoPart(payload.data, pageNum);
}
cli({
site: 'bilibili',
name: 'download',
access: 'read',
description: '下载B站视频(需要 yt-dlp)',
domain: 'www.bilibili.com',
strategy: Strategy.COOKIE,
args: [
{ name: 'bvid', required: true, positional: true, help: 'Video BV ID (e.g., BV1xxx)' },
{ name: 'output', default: './bilibili-downloads', help: 'Output directory' },
{ name: 'quality', default: 'best', help: 'Video quality (best, 1080p, 720p, 480p)' },
{ name: 'force', type: 'boolean', default: false, help: '跳过付费内容预检直接下载(已购买/已充电/已开通会员时用)' },
{ name: 'page', required: false, help: '分P 选集序号(从 1 开始)。多 P 视频下载该集;缺省下载默认 P1' },
],View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the bvid is correct and the video is public (opens at bilibili.com/video/<bvid>).
- Retry later or from a cleaner IP if code is -352/-412 (risk control); use cookies of a logged-in session.
- If code is 'malformed', inspect the raw response — you are likely behind a proxy/firewall returning non-JSON.
- Handle the payload.code in calling code to give the end user a specific message (e.g. -404 → 'video not found').
Example fix
// before
const part = await loadSelectedPart(page, bvid, pageNum);
// after
let part;
try {
part = await loadSelectedPart(page, bvid, pageNum);
} catch (e) {
if (String(e.message).includes('-404')) throw new Error(`视频不存在: ${bvid}`);
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!/^BV[0-9A-Za-z]{10}$/.test(bvid)) throw new Error(`invalid bvid: ${bvid}`); Type guard
function isOkPayload(p) {
return typeof p === 'object' && p !== null && p.code === 0 && 'data' in p;
} Try / catch
try {
const part = loadSelectedPart(page, bvid, pageNum);
} catch (e) {
const m = String(e.message);
if (m.includes('-404')) return null; // video gone
if (m.includes('-352') || m.includes('-412')) return retryWithBackoff();
throw e;
} Prevention
- Validate bvid format (BV + 10 alphanumerics) before calling
- Check the video opens in a browser before automating
- Use a logged-in session to reduce risk-control responses
- Rate-limit calls to avoid -412/-352
When it happens
Trigger: Calling bilibili download with a bvid whose view API responds with code!==0 (e.g. -404 video not found, -400 invalid bvid, -352 risk-control) or with a body that is not a JSON object.
Common situations: Typo in the BV id, deleted/private/region-locked video, Bilibili risk control returning -352/-412, or a proxy/captive portal returning an HTML error page that fails object validation (code 'malformed').
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
- 获取关注列表失败: ${payload.message} (${payload.code})
- Bilibili creator comparison API returned a malformed envelop
- Bilibili creator comparison API failed: ${message} (${payloa
- Bilibili creator comparison
- Bilibili creator comparison request failed: ${detail}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/df73ab0da8a357d5.
Report an issue: GitHub.