jackwener/OpenCLI · error · CommandExecutionError
Bilibili view API returned a malformed payload during paid-c
Error message
Bilibili view API returned a malformed payload during paid-content pre-check
What it means
During the pre-download paid-content check, the /x/web-interface/view response either wasn't an object or lacked a `code` field, so its payment rights cannot be evaluated. The library throws this structured error instead of assuming the video is free (unlike network errors, which are swallowed and treated as pass-through).
Source
Thrown at clis/bilibili/download.js:39
function isObject(value) {
return value && typeof value === 'object' && !Array.isArray(value);
}
/**
* 下载前付费预检:付费/会员视频 yt-dlp 只能拿到试看流或直接失败,
* 与其跑一半吐一坨 yt-dlp stderr,不如提前抛结构化 PAID_CONTENT(exit 77)。
*
* 大会员专享(vip)会再查一次 nav API:当前账号大会员有效就放行(cookie 喂给
* yt-dlp 能下完整流)。ugc_pay / upower 的购买/充电状态没有廉价查询端点,保守
* 拦截,已购用户用 --force 跳过。预检自身的 API 失败不阻塞下载(保持旧行为)。
*/
async function assertNotPaidContent(page, bvid) {
let d;
try {
const payload = await apiGet(page, '/x/web-interface/view', { params: { bvid } });
if (!isObject(payload) || !Object.hasOwn(payload, 'code')) {
throw new CommandExecutionError('Bilibili view API returned a malformed payload during paid-content pre-check');
}
if (payload.code !== 0)
return;
if (!isObject(payload.data) || !isObject(payload.data.rights)) {
throw new CommandExecutionError('Bilibili view API returned malformed paid-content metadata');
}
d = payload.data;
}
catch (error) {
if (error instanceof CommandExecutionError) {
throw error;
}
return;
}
const rights = d.rights;
const paymentType = rights.pay
? 'vip'
: (rights.ugc_pay || rights.arc_pay)View on GitHub (pinned to 49907e53dc)
Solutions
- Re-run the command; risk-control interstitials are often transient.
- Refresh the stored Bilibili cookies / re-login so requests aren't challenged.
- Check network path (proxy/VPN) for HTML injection or blocked domains.
- Clear cookies entirely to bypass pre-check failures (pre-check failures other than this structured error are non-fatal by design).
Example fix
// caller-side guard mirroring the check
const payload = await apiGet(page, '/x/web-interface/view', { params: { bvid } });
if (!payload || typeof payload !== 'object' || Array.isArray(payload) || !Object.hasOwn(payload, 'code')) {
// treat as malformed: skip pre-check or retry
} Defensive patterns
Strategy: try-catch
Validate before calling
const res = await fetch('https://api.bilibili.com/x/web-interface/view?bvid=' + bvid, { headers: { cookie } });
const body = await res.text();
let payload; try { payload = JSON.parse(body); } catch { /* HTML/risk-control page */ }
if (!payload || typeof payload !== 'object' || Array.isArray(payload) || !('code' in payload)) { /* retry or refresh cookies */ } Type guard
function isViewEnvelope(v) {
return Boolean(v) && typeof v === 'object' && !Array.isArray(v) && Object.hasOwn(v, 'code');
} Try / catch
try {
await download(bvid);
} catch (e) {
if (/malformed payload during paid-content pre-check/.test(e.message)) {
// refresh cookies / retry; risk-control interstitials are often transient
} else throw e;
} Prevention
- Keep Bilibili cookies fresh to avoid risk-control challenges
- Avoid heavy request rates that trigger anti-bot interstitials
- Don't route through proxies that inject/modify HTML
- Retry once on malformed envelopes before escalating
When it happens
Trigger: apiGet to /x/web-interface/view succeeds at transport level but returns a non-object body, HTML instead of JSON, or JSON without `code` — e.g. Bilibili risk-control interstitial, gateway HTML error page, or API format change.
Common situations: Bilibili anti-bot risk control serving HTML challenges; region-locked or CDN edge returning error pages; expired/invalid cookies producing an unexpected body shape; corporate proxy injecting content.
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
- 获取视频信息失败: ${view?.message ?? 'unknown'} (${view?.code})
- 获取视频播放信息失败: ${payload.message} (${payload.code})
- Bilibili user search returned malformed mid for ${input}
- ${label} returned a malformed payload
- Cannot resolve aid for bvid: ${bvid}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/c21ce2f410d7a0b7.
Report an issue: GitHub.