jackwener/OpenCLI · error · CommandExecutionError
获取视频播放信息失败: ${err?.message || err}
Error message
获取视频播放信息失败: ${err?.message || err} What it means
Wrapping error: the Wbi-signed call to /x/player/wbi/v2 (which returns the subtitle list for a bvid+cid) threw, so the underlying transport error is re-thrown as CommandExecutionError prefixed with 获取视频播放信息失败. Distinct from 437, which handles the API answering with an error code; this fires only when apiGet rejects (network, timeout, signature failure producing a transport-level exception).
Source
Thrown at clis/bilibili/subtitle.js:50
}
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) {
throw new CommandExecutionError(`获取视频播放信息失败: ${err?.message || err}`);
}
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
throw new CommandExecutionError('获取到的视频播放信息对象不符合预期格式');
}
if (payload.code !== 0) {
throw new CommandExecutionError(`获取视频播放信息失败: ${payload.message} (${payload.code})`);
}
const needLoginSubtitle = payload.data?.need_login_subtitle === true;
const subtitles = payload.data?.subtitle?.subtitles;
if (!Array.isArray(subtitles)) {
throw new CommandExecutionError('获取到的字幕列表对象不符合数组格式');
}
if (subtitles.length === 0) {
if (needLoginSubtitle) {
throw new AuthRequiredError('bilibili.com', 'Bilibili subtitles are hidden behind login for this video. Please log in to bilibili.com in Chrome and retry.');
}
throw new EmptyResultError('bilibili subtitle', '此视频没有发现外挂或智能字幕。');
}View on GitHub (pinned to 49907e53dc)
Solutions
- Read the inner message after the prefix for the real cause (timeout vs network vs signature)
- Re-establish the browser session and retry — Wbi signing depends on a live page
- Retry after a short delay if rate limiting is suspected
- Check network/proxy stability to api.bilibili.com
Defensive patterns
Strategy: retry
Try / catch
try {
await run(['bilibili', 'subtitle', bvid]);
} catch (e) {
const m = String(e.message);
if (m.startsWith('获取视频播放信息失败') && !/\(\d+\)/.test(m)) {
await sleep(2000); // then retry once; check network/session if it repeats
} else throw e;
} Prevention
- Keep the attached Chrome session alive during the command (don't close the page)
- Use a logged-in session so Wbi signing works reliably
- Add retry with backoff for transient network failures
When it happens
Trigger: apiGet(page, '/x/player/wbi/v2', {params:{bvid,cid}, signed:true}) rejects — network drop, page context closed, Wbi signing failure, or non-JSON response.
Common situations: Wbi keys rotated/expired in the session; unstable network or proxy; page was navigated away/closed mid-command; heavy rate limiting causing connection resets.
Related errors
- 获取视频分P信息失败: ${error?.message || error}
- 获取视频信息失败: ${err?.message || err}
- 获取视频播放信息失败: ${payload.message} (${payload.code})
- ${label} returned HTTP ${resp.status}: ${summarizeApiError(p
- arXiv API HTTP ${resp.status}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/1e65de648e55da47.
Report an issue: GitHub.