{"record":{"id":"1b734568842e316c","repo":"jackwener/OpenCLI","slug":"error-1b7345","errorCode":null,"errorMessage":"获取到的视频播放信息对象不符合预期格式","messagePattern":"获取到的视频播放信息对象不符合预期格式","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/bilibili/subtitle.js","lineNumber":53,"sourceCode":"        }\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        }\n        const needLoginSubtitle = payload.data?.need_login_subtitle === true;\n        const subtitles = payload.data?.subtitle?.subtitles;\n        if (!Array.isArray(subtitles)) {\n            throw new CommandExecutionError('获取到的字幕列表对象不符合数组格式');\n        }\n        if (subtitles.length === 0) {\n            if (needLoginSubtitle) {\n                throw new AuthRequiredError('bilibili.com', 'Bilibili subtitles are hidden behind login for this video. Please log in to bilibili.com in Chrome and retry.');\n            }\n            throw new EmptyResultError('bilibili subtitle', '此视频没有发现外挂或智能字幕。');\n        }\n        // 3. 选择目标字幕语言\n        const target = kwargs.lang\n            ? subtitles.find((s) => s.lan === kwargs.lang) || subtitles[0]","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/bilibili/subtitle.js#L35-L71","documentation":"The player/v2 endpoint returned something that is not a plain object (null, an array, or a non-object), so the code cannot read .code/.data from it. The library throws this CommandExecutionError instead of dereferencing undefined properties. It guards against Bilibili returning an unexpected payload shape (e.g. an HTML/JSON array interstitial or empty body parsed oddly).","triggerScenarios":"payload from apiGet('/x/player/wbi/v2') is null, an Array, or typeof !== 'object' — i.e. the JSON parse succeeded but the top-level shape isn't the expected {code,data,...} envelope.","commonSituations":"Bilibili returning an error page/empty body that still parsed as JSON; a proxy or captive portal intercepting the response; API schema drift for certain content types; hitting an endpoint variant that returns a bare array.","solutions":["Retry the command — transient interstitials often resolve on a second attempt","Verify you are not behind a proxy/captive portal mangling responses to api.bilibili.com","Log the raw payload (log in a debug run) to see what actually came back and adjust expectations","Ensure the session is logged in; some content types return degenerate payloads when unauthenticated"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isApiEnvelope(p) {\n  return p != null && typeof p === 'object' && !Array.isArray(p) && typeof p.code === 'number';\n}","tryCatchPattern":"try {\n  await run(['bilibili', 'subtitle', bvid]);\n} catch (e) {\n  if (String(e.message).includes('不符合预期格式')) {\n    // capture raw response for debugging; retry once in case of a transient interstitial\n  } else throw e;\n}","preventionTips":["Avoid proxies/captive portals that can mangle API responses","Retry once on shape errors — they are often transient","Log raw API responses when debugging schema drift"],"tags":["api","data-shape","bilibili","validation"],"backgroundTag":"unexpected-response-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}