jackwener/OpenCLI · error · CommandExecutionError
Bilibili view API did not return pages[] for --page selectio
Error message
Bilibili view API did not return pages[] for --page selection
What it means
selectVideoPart requires the view API's data.pages[] array as the source-of-truth for --page (分P) selection. If the payload has no pages array or it is empty, the library throws rather than guessing a cid, because single-page videos can omit pages and selecting a part without one would be wrong.
Source
Thrown at clis/bilibili/utils.js:119
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');
if (apiPage === pageNum) {
matches.push(entry);
}
}
if (matches.length > 1) {
throw new CommandExecutionError(`Bilibili view API returned duplicate page entries for p=${pageNum}`);
}
const part = matches[0];
if (!part) {
const total = pages.length || viewData?.videos || 1;
throw new CommandExecutionError(`分P 序号超出范围:p=${pageNum}(该视频共 ${total} 集)`);View on GitHub (pinned to 49907e53dc)
Solutions
- Drop the --page flag for single-part videos — pages[] is absent when there is only one part.
- Re-fetch the view API and confirm data.pages exists before selecting a part.
- Check that you parsed the right response level: pages lives under data.pages of the view payload.
- Handle the error by falling back to the default (first/only) part if your use case allows.
Example fix
// before
await cmd(['bili', 'download', url, '--page', '2']); // single-P video, no pages[]
// after
const view = await getViewData(url);
if (Array.isArray(view.pages) && view.pages.length > 0) {
await cmd(['bili', 'download', url, '--page', '2']);
} else {
await cmd(['bili', 'download', url]); // default single part
} Defensive patterns
Strategy: validation
Validate before calling
const pages = Array.isArray(viewData?.pages) ? viewData.pages : null;
if (!pages || pages.length === 0) { /* fall back to single-part download: omit --page */ } Type guard
function hasPages(v){ return !!v && typeof v==='object' && Array.isArray(v.pages) && v.pages.length>0; } Try / catch
try { const part = selectVideoPart(viewData, pageNum); } catch (e) { if (/did not return pages/.test(e.message)) return downloadDefaultPart(viewData); throw e; } Prevention
- Only pass --page when the video actually has multiple parts (pages[] non-empty).
- Treat absent pages[] as a single-part video and use the default part.
- Cache view responses briefly but re-validate shape before reuse.
- Check data.pages (not top-level pages) when inspecting the view payload.
When it happens
Trigger: Calling selectVideoPart(viewData, n) where viewData is null/undefined, viewData.pages is not an array, or pages is an empty array — typically because --page was passed for a video whose view response lacks pages[].
Common situations: Passing --page 1 to a single-part (单P) video whose API response omits pages[]; Bilibili returning an error-shaped body that slipped past earlier checks; stale cached view data.
Related errors
- 分P 序号超出范围:p=${pageNum}(该视频共 ${total} 集)
- 获取到的视频播放信息对象不符合预期格式
- Bilibili view API returned a malformed ${label}
- Bilibili view API returned a malformed pages[] entry
- Bilibili view API returned duplicate page entries for p=${pa
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/d0a9956d96ce5038.
Report an issue: GitHub.