jackwener/OpenCLI · error · CommandExecutionError

msg

Error message

msg

What it means

For any captionData.error other than the recognized 'No captions available' case, the CLI throws CommandExecutionError with the page-supplied error message (msg), which may include the list of available caption tracks. This represents a genuine fetch/parse/HTTP failure in obtaining caption info, as opposed to a legitimate empty result.

Source

Thrown at clis/youtube/transcript.js:453

          available,
          requestedLang: langPref || null,
          langMatched: !!(langPref && track.languageCode === langPref),
          langPrefixMatched: !!(langPref && track.languageCode !== langPref && track.languageCode.startsWith(langPref))
        };
      })()
    `));
        if (!segments && (!captionData || typeof captionData !== 'object' || Array.isArray(captionData))) {
            throw new CommandExecutionError(`Failed to get caption info: ${typeof captionData === 'string' ? captionData : 'malformed response'}`);
        }
        if (captionData?.error) {
            const msg = `${captionData.error}${captionData.available ? ' (available: ' + captionData.available.join(', ') + ')' : ''}`;
            // "No captions available" 是合法 empty 数据条件(作者没开字幕 + YT 没自动生成),
            // 与 bilibili subtitle 的 EmptyResultError 同模式。下游应按 code EMPTY_RESULT 跳过
            // 重试和 softFail 计数。其它 error(HTTP / parse / 短暂空响应)仍按 fetch 失败抛。
            if (captionData.error === 'No captions available for this video') {
                throw new EmptyResultError('youtube transcript', '该视频没有字幕(作者未开启 + 无自动字幕)。');
            }
            throw new CommandExecutionError(msg);
        }
        if (!segments && typeof captionData?.captionUrl !== 'string') {
            throw new CommandExecutionError('Malformed caption info payload');
        }
        // Warn if --lang was specified but not matched
        if (captionData?.requestedLang && !captionData.langMatched && !captionData.langPrefixMatched) {
            console.error(`Warning: --lang "${captionData.requestedLang}" not found. Using "${captionData.language}" instead. Available: ${captionData.available.join(', ')}`);
        }
        // Step 2: Fetch caption XML and parse segments
        // Ensure caption URL requests srv3 XML format — YouTube may return empty
        // responses when no explicit format is specified.
        if (!segments) {
            const originalCaptionUrl = captionData.captionUrl;
            let captionUrl = originalCaptionUrl;
            if (!/[&?]fmt=/.test(originalCaptionUrl)) {
                captionUrl = originalCaptionUrl + (originalCaptionUrl.includes('?') ? '&' : '?') + 'fmt=srv3';
            }
            segments = normalizeSegmentsPayload(await page.evaluate(`

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read msg — it may include available tracks or the underlying HTTP reason — and address that cause.
  2. Retry after a short backoff; the source comment classifies these as transient fetch failures eligible for retry.
  3. Verify the video is playable in the automated browser (not deleted/region-blocked).
  4. Update the CLI if the message indicates a page-structure mismatch.

Example fix

// before
const segments = await getSegments(videoId);
// after
const segments = await retry(() => getSegments(videoId), { retries: 2, backoffMs: 1000 }); // transient caption fetch errors only
Defensive patterns

Strategy: retry

Try / catch

try {
  const segments = await getSegments(videoId);
} catch (err) {
  if (!(err instanceof EmptyResultError)) {
    // transient fetch/parse failure per source comment — retry with backoff
    await sleep(1000);
    return getSegments(videoId);
  }
  throw err;
}

Prevention

When it happens

Trigger: `segments` where the injected caption-info script returns {error: <anything else>} — e.g. HTTP failures fetching the player response, transient empty responses, or page-side exceptions other than the no-captions sentinel.

Common situations: Rate limiting or temporary YouTube errors; network glitches in the automated browser; player API responses failing mid-SPA navigation; video unavailable/deleted pages.

Related errors


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