jackwener/OpenCLI · error · CommandExecutionError
Bilibili view API returned a malformed ${label}
Error message
Bilibili view API returned a malformed ${label} What it means
readApiPositiveInteger validates that a numeric field from the Bilibili view API (e.g. page, cid) is a positive integer — either a number or a numeric string matching /^[1-9]\d*$/. If the value is missing, zero, negative, fractional, non-numeric, or an unsafe integer, the library fails closed because page/cid are the source-of-truth for selecting a video part and using a malformed one would target the wrong resource.
Source
Thrown at clis/bilibili/utils.js:108
if (typeof value !== 'string' || !/^[1-9]\d*$/.test(value)) {
throw new ArgumentError(`--page must be a positive decimal integer, got: ${String(value)}`);
}
const n = Number(value);
if (!Number.isSafeInteger(n)) {
throw new ArgumentError(`--page is too large: ${value}`);
}
return n;
}
function readApiPositiveInteger(value, label) {
if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 1) {
return value;
}
if (typeof value === 'string' && /^[1-9]\d*$/.test(value)) {
const n = Number(value);
if (Number.isSafeInteger(n)) return n;
}
throw new CommandExecutionError(`Bilibili view API returned a malformed ${label}`);
}
/**
* 从 view API 的 data.pages 数组取第 N 集(1-based)。
* page/cid 都以 view API 的 pages[] 为 source-of-truth;缺失、重复或畸形都 fail closed。
* 返回该集 raw 对象(含 cid / part(分集标题) / page / duration)。
*/
export function selectVideoPart(viewData, pageNum) {
const pages = Array.isArray(viewData?.pages) ? viewData.pages : null;
if (!pages || pages.length === 0) {
throw new CommandExecutionError('Bilibili view API did not return pages[] for --page selection');
}
const matches = [];
for (const entry of pages) {
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
throw new CommandExecutionError('Bilibili view API returned a malformed pages[] entry');
}
const apiPage = readApiPositiveInteger(entry.page, 'page number');View on GitHub (pinned to 49907e53dc)
Solutions
- Re-fetch the view API response — the malformed value is often transient (CDN/cache glitch).
- Verify the video actually has multi-page data (check data.pages exists and each entry has page/cid).
- Log the full raw response body to see which field and value failed validation.
- If Bilibili changed the schema, update the validation/field extraction in clis/bilibili/utils.js accordingly.
Example fix
// before
const part = viewData.pages[0];
const cid = part.cid; // may be undefined -> CommandExecutionError
// after
if (typeof part?.cid === 'number' && Number.isSafeInteger(part.cid) && part.cid > 0) {
const cid = part.cid;
} Defensive patterns
Strategy: validation
Validate before calling
function isValidPart(p){ return p && typeof p==='object' && Number.isSafeInteger(p.page) && p.page>0 && Number.isSafeInteger(p.cid) && p.cid>0; }
const usable = (viewData?.pages ?? []).filter(isValidPart); Type guard
function isPositiveInteger(v){ return (typeof v==='number' || (typeof v==='string' && /^[1-9]\d*$/.test(v))) && Number.isSafeInteger(Number(v)) && Number(v)>0; } Try / catch
try { const part = selectVideoPart(viewData, pageNum); } catch (e) { if (/malformed/.test(e.message)) { viewData = await refetchViewData(url); /* retry once */ } else throw e; } Prevention
- Always validate pages[] entries (page/cid present, positive safe integers) before using them.
- Re-fetch the view API once on malformed responses — many are transient CDN glitches.
- Pin/monitor the Bilibili view API schema in tests with recorded fixtures.
- Fail fast: log the raw response body when validation fails to speed diagnosis.
When it happens
Trigger: Bilibili's /x/web-interface/view endpoint returns a pages[] entry (or another validated field) whose `page` or `cid` is undefined, null, 0, a float, a negative number, a non-numeric string, or a number beyond Number.MAX_SAFE_INTEGER.
Common situations: Bilibili API schema changes or partial responses during incidents; caching proxies/CDNs returning truncated JSON; mocked or replayed responses missing fields; an API regression returning null cid for newly uploaded videos.
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
- Bilibili view API returned a malformed pages[] entry
- 获取到的视频播放信息对象不符合预期格式
- Bilibili view API did not return pages[] for --page selectio
- Bilibili view API returned duplicate page entries for p=${pa
- 分P 序号超出范围:p=${pageNum}(该视频共 ${total} 集)
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/2fc6777bbf1a5985.
Report an issue: GitHub.