jackwener/OpenCLI · error · CommandExecutionError
字幕条目缺少 subtitle_url 字段
Error message
字幕条目缺少 subtitle_url 字段
What it means
A CommandExecutionError thrown when the selected subtitle track object does not contain a subtitle_url property. The library picks the track matching kwargs.lang (or the first track) and requires subtitle_url to know where the CDN JSON subtitle file lives. This indicates the API returned malformed or unexpectedly shaped subtitle data.
Source
Thrown at clis/bilibili/subtitle.js:74
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', '此视频没有发现外挂或智能字幕。');
}
// 3. 选择目标字幕语言
const target = kwargs.lang
? subtitles.find((s) => s.lan === kwargs.lang) || subtitles[0]
: subtitles[0];
if (!target || typeof target !== 'object' || !Object.hasOwn(target, 'subtitle_url')) {
throw new CommandExecutionError('字幕条目缺少 subtitle_url 字段');
}
const targetSubUrl = typeof target.subtitle_url === 'string' ? target.subtitle_url.trim() : '';
if (!targetSubUrl) {
throw new AuthRequiredError('bilibili.com', '[风控拦截/未登录] 获取到的 subtitle_url 为空!请确保 CLI 已成功登录且风控未封锁此账号。');
}
const finalUrl = targetSubUrl.startsWith('//') ? 'https:' + targetSubUrl : targetSubUrl;
if (!/^https?:\/\//i.test(finalUrl)) {
throw new CommandExecutionError(`字幕 URL 非法: ${finalUrl}`);
}
// 4. 解析并拉取 CDN 的 JSON 文件
const fetchJs = `
(async () => {
const url = ${JSON.stringify(finalUrl)};
const res = await fetch(url);
const text = await res.text();
if (text.startsWith('<!DOCTYPE') || text.startsWith('<html')) {
return { error: 'HTML', text: text.substring(0, 100), url };View on GitHub (pinned to 49907e53dc)
Solutions
- Drop the --lang option so the library falls back to subtitles[0] instead of a possibly malformed matching track.
- Re-run the command — transient API payloads sometimes omit fields.
- Check whether a Bilibili API update renamed subtitle_url (inspect the raw /player/wbi/v2 response).
- Update the CLI/library to a version matching the current API shape.
Example fix
// before
await run('bilibili subtitle', { url, lang: 'ai-zh' });
// after
await run('bilibili subtitle', { url }); // let it pick the first valid track Defensive patterns
Strategy: validation
Validate before calling
// After receiving the API list yourself (or after a failure), verify entries: const valid = Array.isArray(subtitles) && subtitles.some(s => s && typeof s === 'object' && 'subtitle_url' in s);
Type guard
const hasSubtitleUrl = (t) => !!t && typeof t === 'object' && 'subtitle_url' in t;
Try / catch
try {
await run('bilibili subtitle', { url, lang });
} catch (e) {
if (/subtitle_url/.test(e.message)) {
return run('bilibili subtitle', { url }); // retry without lang filter
}
throw e;
} Prevention
- Avoid pinning --lang to tracks that may be metadata-only.
- Keep the library updated for Bilibili API shape changes.
- Retry once without the lang filter on this error.
When it happens
Trigger: The chosen subtitles[i] entry lacks subtitle_url — e.g. the player API response shape changed, or the entry matched by kwargs.lang is a stub/metadata-only track.
Common situations: Passing a lang code that matches a track with no downloadable URL; Bilibili changing/renaming the subtitle_url field in an API update; mocking or cached API responses missing the field.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- 字幕获取结果对象不符合预期格式
- 解析到的字幕列表对象不符合数组格式
- 字幕片段缺少有效 from/to 时间戳
- Bilibili relation query returned a malformed attribute
- 此视频没有发现外挂或智能字幕。
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3a12c3170ebda4f2.
Report an issue: GitHub.