{"record":{"id":"5e5ae152fb14ee6e","repo":"jackwener/OpenCLI","slug":"view-api-cid-bvid-bvid","errorCode":null,"errorMessage":"无法从 view API 拿到 cid (bvid=${bvid})","messagePattern":"无法从 view API 拿到 cid \\(bvid=(.+?)\\)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/subtitle.js","lineNumber":39,"sourceCode":"        const selectedPage = parsePageArg(kwargs.page);\n        // 1. 通过 view API 拿 cid。\n        //    以前的实现走 page.goto(/video/<bvid>) + window.__INITIAL_STATE__.videoData.cid，\n        //    bangumi 绑定的 bvid（番剧/纪录片/电影/综艺）页面 state 不在 videoData 而在 epList，\n        //    导致 SELECTOR 错。view API 接受任何 bvid（UGC + PGC 都通），且不依赖 DOM 结构。\n        let view;\n        try {\n            view = await apiGet(page, '/x/web-interface/view', { params: { bvid } });\n        }\n        catch (err) {\n            throw new CommandExecutionError(`获取视频信息失败: ${err?.message || err}`);\n        }\n        if (view?.code !== 0) {\n            throw new CommandExecutionError(`获取视频信息失败: ${view?.message ?? 'unknown'} (${view?.code})`);\n        }\n        // --page 给定时用该集 cid（selectVideoPart 越界抛错）；缺省取整集默认 cid（P1，旧行为）。\n        const cid = selectedPage != null ? selectVideoPart(view?.data, selectedPage).cid : view?.data?.cid;\n        if (!cid) {\n            throw new CommandExecutionError(`无法从 view API 拿到 cid (bvid=${bvid})`);\n        }\n        // 2. 用带 Wbi 签名的 player/v2 拿字幕列表（之前 evaluate 里 fetch 因为没签名会 403）\n        let payload;\n        try {\n            payload = await apiGet(page, '/x/player/wbi/v2', {\n                params: { bvid, cid },\n                signed: true,\n            });\n        }\n        catch (err) {\n            throw new CommandExecutionError(`获取视频播放信息失败: ${err?.message || err}`);\n        }\n        if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {\n            throw new CommandExecutionError('获取到的视频播放信息对象不符合预期格式');\n        }\n        if (payload.code !== 0) {\n            throw new CommandExecutionError(`获取视频播放信息失败: ${payload.message} (${payload.code})`);\n        }","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/subtitle.js#L21-L57","documentation":"After a successful view API call, the code extracts a cid — the specific part's content id — either via selectVideoPart (when --page is given) or view.data.cid (default P1). If the resulting cid is falsy it throws this CommandExecutionError, since the player/v2 subtitle API cannot be called without a cid. It indicates the view response had an unexpected shape or the chosen part lacks a cid.","triggerScenarios":"view.data.cid missing on a default call; --page N pointing at a part whose cid is undefined; a PGC/bangumi bvid whose view data nests parts differently than expected.","commonSituations":"Bangumi/PGC content where the standard view payload lacks the expected cid fields; --page out of the parts list producing an object without cid; Bilibili API schema change for certain content types.","solutions":["Confirm the bvid is a normal UGC video (try omitting --page to use the default P1 cid)","Check the --page value is within range; verify the video actually has that many parts","Open the video in a browser and confirm it plays; if it's a bangumi episode, use the appropriate ep/ss id handling instead","If the API schema changed, update utils.js selectVideoPart / field paths to match current view API responses"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!/^BV[0-9A-Za-z]{10}$/.test(bvid)) throw new Error('invalid bvid format');\n// for --page: confirm the part index is plausible\nif (pageArg != null && !(Number.isInteger(pageArg) && pageArg >= 1)) throw new Error('bad --page');","typeGuard":null,"tryCatchPattern":"try {\n  await run(['bilibili', 'subtitle', bvid, '--page', String(n)]);\n} catch (e) {\n  if (String(e.message).includes('无法从 view API 拿到 cid')) {\n    // retry without --page (default P1) or verify the video is a normal UGC video\n  } else throw e;\n}","preventionTips":["Prefer standard UGC video bvids; handle bangumi content with dedicated tooling","Omit --page unless you know the video is multi-part and the index is in range","Validate bvid format before invoking the command"],"tags":["api","bilibili","data-shape","cid"],"backgroundTag":"missing-required-field","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}