jackwener/OpenCLI · error · CommandExecutionError

获取视频信息失败: ${err?.message || err}

Error message

获取视频信息失败: ${err?.message || err}

What it means

Wrapping error: the call to Bilibili's /x/web-interface/view API (which resolves bvid -> video metadata incl. cid) threw, so the original network/transport error is re-thrown as CommandExecutionError prefixed with 获取视频信息失败. The underlying cause is embedded via err?.message. This is thrown only when apiGet itself fails (network, timeout, non-JSON response), not when the API returns an error code (that hits error 433).

Source

Thrown at clis/bilibili/subtitle.js:31

        { name: 'lang', required: false, help: '字幕语言代码 (如 zh-CN, en-US, ai-zh),默认取第一个' },
        { name: 'page', required: false, help: '分P 选集序号(从 1 开始)。多 P 视频取该集字幕;缺省取默认 P1' },
    ],
    columns: ['index', 'from', 'to', 'content'],
    func: async (page, kwargs) => {
        if (!page)
            throw new CommandExecutionError('Browser session required for bilibili subtitle');
        const bvid = await resolveBvid(kwargs.bvid);
        const selectedPage = parsePageArg(kwargs.page);
        // 1. 通过 view API 拿 cid。
        //    以前的实现走 page.goto(/video/<bvid>) + window.__INITIAL_STATE__.videoData.cid,
        //    bangumi 绑定的 bvid(番剧/纪录片/电影/综艺)页面 state 不在 videoData 而在 epList,
        //    导致 SELECTOR 错。view API 接受任何 bvid(UGC + PGC 都通),且不依赖 DOM 结构。
        let view;
        try {
            view = await apiGet(page, '/x/web-interface/view', { params: { bvid } });
        }
        catch (err) {
            throw new CommandExecutionError(`获取视频信息失败: ${err?.message || err}`);
        }
        if (view?.code !== 0) {
            throw new CommandExecutionError(`获取视频信息失败: ${view?.message ?? 'unknown'} (${view?.code})`);
        }
        // --page 给定时用该集 cid(selectVideoPart 越界抛错);缺省取整集默认 cid(P1,旧行为)。
        const cid = selectedPage != null ? selectVideoPart(view?.data, selectedPage).cid : view?.data?.cid;
        if (!cid) {
            throw new CommandExecutionError(`无法从 view API 拿到 cid (bvid=${bvid})`);
        }
        // 2. 用带 Wbi 签名的 player/v2 拿字幕列表(之前 evaluate 里 fetch 因为没签名会 403)
        let payload;
        try {
            payload = await apiGet(page, '/x/player/wbi/v2', {
                params: { bvid, cid },
                signed: true,
            });
        }
        catch (err) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check network connectivity/proxy settings to api.bilibili.com and retry
  2. Verify the bvid/URL resolves (open it in a browser); an invalid bvid can surface here
  3. Refresh/re-establish the browser session and cookies, then retry
  4. Inspect the inner message after the prefix — it contains the real cause and fix accordingly
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await run(['bilibili', 'subtitle', bvid]);
} catch (e) {
  const m = String(e.message);
  if (m.startsWith('获取视频信息失败') && !/\(\d+\)/.test(m)) {
    // transport failure — check network/proxy, then retry with backoff
  } else throw e;
}

Prevention

When it happens

Trigger: apiGet(page, '/x/web-interface/view', {params:{bvid}}) rejects: network failure, timeout, HTML returned instead of JSON, Wbi/page session broken, or DNS/proxy issues.

Common situations: No network or blocked access to api.bilibili.com; corporate proxy; bvid unresolved invalid causing page navigation fetch path failure; page session expired mid-command; rate limiting returning HTML interstitial.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/1fe9d2cddede7bcb. Report an issue: GitHub.