jackwener/OpenCLI · error · CommandExecutionError
Bilibili view API failed: ${payload.message} (${payload.code
Error message
Bilibili view API failed: ${payload.message} (${payload.code}) What it means
After fetching /x/web-interface/view, the video command checks payload.code; Bilibili APIs signal failure via a non-zero code plus a message. This CommandExecutionError surfaces the API's own message and code (e.g. -404 video not found, -403 forbidden, -352 risk control) instead of failing opaquely.
Source
Thrown at clis/bilibili/video.js:69
// Resolve BV ID from three advertised input forms:
// 1. Bare "BV..." id
// 2. Full bilibili.com/video/<BV>... URL (with or without query string / www / m.)
// 3. b23.tv short link (delegated to resolveBvid)
// resolveBvid() alone handles (1) and (3) but not (2), so we pre-extract
// from bilibili URLs before falling through.
const input = String(kwargs.bvid ?? '').trim();
const bilibiliUrlMatch = input.match(/bilibili\.com\/(?:video|bangumi\/play)\/(BV[A-Za-z0-9]+)/i);
const bvid = bilibiliUrlMatch ? bilibiliUrlMatch[1] : await resolveBvid(input);
// Navigate to video page first so subsequent api call shares a primed session.
await page.goto(`https://www.bilibili.com/video/${bvid}/`);
const payload = unwrapBrowserResult(await apiGet(page, '/x/web-interface/view', {
params: { bvid },
}));
requireObject(payload, 'Bilibili view API');
if (payload.code !== 0) {
throw new CommandExecutionError(`Bilibili view API failed: ${payload.message} (${payload.code})`);
}
const d = requireObject(payload.data, 'Bilibili view API data');
const stat = d.stat || {};
const owner = d.owner || {};
// 付费/会员标记:view API 的 rights 位 + 充电专属字段本来就在响应里,
// 透出给下游在下载/截屏前判断"拿不到视频流"。
// rights.pay=1 → 付费 OGV(大会员专享/单点付费番剧、影视;实测会员番剧单集 pay=1)
// rights.ugc_pay=1 / arc_pay=1 → UGC 单点付费 / 付费合集
// is_upower_exclusive=true → 充电专属视频
// redirect_url 非空(指向 /bangumi/play/ep<id>)= OGV 内容,细分可再查 pgc season API。
const rights = requireObject(d.rights, 'Bilibili view API data.rights');
const rightsPay = readOptionalFlag(rights.pay, 'Bilibili rights.pay');
const rightsUgcPay = readOptionalFlag(rights.ugc_pay, 'Bilibili rights.ugc_pay');
const rightsArcPay = readOptionalFlag(rights.arc_pay, 'Bilibili rights.arc_pay');
const upowerExclusive = readOptionalFlag(d.is_upower_exclusive, 'Bilibili is_upower_exclusive');
const paymentType = rightsPayView on GitHub (pinned to 49907e53dc)
Solutions
- Verify the BV ID / URL is correct and the video is still public
- Retry with backoff if the code indicates rate limiting (-412, -352) or use a fresh browser session/IP
- Log in / refresh the browser session if the video requires authentication
- Check the code against Bilibili API error docs (e.g. -404 = not found) to choose the right remedy
Example fix
// before
const d = requireObject(payload.data, 'Bilibili view API data');
// after
if (payload.code !== 0) {
if (payload.code === -404) console.error('Video not found — check the BV ID');
else throw new CommandExecutionError(`Bilibili view API failed: ${payload.message} (${payload.code})`);
return;
}
const d = requireObject(payload.data, 'Bilibili view API data'); Defensive patterns
Strategy: try-catch
Validate before calling
// validate BV id format before calling
if (!/^BV[0-9A-Za-z]{10}$/.test(bvid)) throw new Error(`invalid bvid: ${bvid}`); Type guard
null
Try / catch
try { const info = await videoInfo(bvid); }
catch (e) {
if (e instanceof CommandExecutionError && e.message.startsWith('Bilibili view API failed')) {
const code = Number(e.message.match(/\((-?\d+)\)$/)?.[1]);
if (code === -404) console.error('Video not found');
else if ([-412, -352].includes(code)) await sleep(5000); // retry on rate-limit
else throw e;
} else throw e;
} Prevention
- Validate bvid format before API calls
- Back off on rate-limit codes (-412, -352)
- Keep sessions logged in for restricted content
- Distinguish per-code handling instead of one generic retry
When it happens
Trigger: Any non-zero code from the view API: invalid/nonexistent bvid, region-locked or deleted video, rate limiting (-412/-352), or requiring login for mature content.
Common situations: Typo in the BV ID; video deleted or made private; accessing from a blocked region/IP; hitting Bilibili rate limits after many rapid requests.
Related errors
- Bilibili creator comparison API failed: ${message} (${payloa
- 获取视频分P信息失败: ${payload?.message ?? 'unknown'} (${payload?.cod
- 获取关注列表失败: ${payload.message} (${payload.code})
- Bilibili relation query returned a malformed attribute
- [风控拦截/未登录] 获取到的 subtitle_url 为空!请确保 CLI 已成功登录且风控未封锁此账号。
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/d35d0288cfb5d377.
Report an issue: GitHub.