jackwener/OpenCLI · error · CommandExecutionError

获取到的字幕列表对象不符合数组格式

Error message

获取到的字幕列表对象不符合数组格式

What it means

The player/v2 payload parsed fine, but data.subtitle.subtitles is not an array (missing or wrong type). The command requires the subtitle list container to be an array to proceed with language selection. This is a structural guard against Bilibili omitting the subtitle field for videos with no subtitle support or when the response shape changes.

Source

Thrown at clis/bilibili/subtitle.js:61

        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', '此视频没有发现外挂或智能字幕。');
        }
        // 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 已成功登录且风控未封锁此账号。');
        }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Confirm the video actually has subtitles (check the CC button in the web player)
  2. Retry while logged in — some responses omit subtitle data when unauthenticated
  3. Check whether the video type supports subtitles at all (livestream/audiobook won't)
  4. If Bilibili changed the schema, update the payload.data?.subtitle?.subtitles path in subtitle.js
Defensive patterns

Strategy: type-guard

Type guard

function hasSubtitleArray(payload) {
  return Array.isArray(payload?.data?.subtitle?.subtitles);
}

Try / catch

try {
  const rows = await run(['bilibili', 'subtitle', bvid]);
} catch (e) {
  if (String(e.message).includes('不符合数组格式')) {
    // treat as 'video has no subtitle support' rather than a crash
  } else throw e;
}

Prevention

When it happens

Trigger: payload.data?.subtitle?.subtitles is undefined or not an array — videos without any subtitle track container, or schema drift where subtitles move elsewhere.

Common situations: Live streams or audio content that has no subtitle data; extremely old videos; unauthenticated responses that strip the subtitle object; Bilibili A/B testing different response shapes.

Related errors


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