jackwener/OpenCLI · error · AuthRequiredError

www.youtube.com

Error message

www.youtube.com

What it means

AuthRequiredError thrown by `youtube history` when the SAPISID cookie is missing from www.youtube.com. Watch history is a private, authenticated surface; the library needs the SAPISID cookie to compute the SAPISIDHASH authorization header for InnerTube API calls. No network request is made — the check fails before evaluation.

Source

Thrown at clis/youtube/history.js:51

cli({
    site: 'youtube',
    name: 'history',
    access: 'read',
    description: 'Get YouTube watch history',
    domain: 'www.youtube.com',
    strategy: Strategy.COOKIE,
    args: [
        { name: 'limit', type: 'int', default: DEFAULT_LIMIT, help: 'Max videos to return (default 30, max 200)' },
    ],
    columns: ['rank', 'title', 'channel', 'views', 'duration', 'url'],
    func: async (page, kwargs) => {
        const limit = normalizeLimit(kwargs.limit);
        await prepareYoutubeApiPage(page);

        const sapisid = await readYoutubeSapisid(page);
        if (!sapisid) {
            throw new AuthRequiredError('www.youtube.com', 'Not logged in (SAPISID cookie missing)');
        }

        const result = await page.evaluate(`
      (async () => {
        ${SAPISID_HASH_FN}

        const limit = ${limit};
        const maxPages = ${MAX_PAGES};
        const requestTimeoutMs = ${REQUEST_TIMEOUT_SECONDS * 1000};
        const cfg = window.ytcfg?.data_ || {};
        const apiKey = cfg.INNERTUBE_API_KEY;
        const context = cfg.INNERTUBE_CONTEXT;
        if (!apiKey || !context) {
          return { error: 'config', message: 'YouTube InnerTube config not found' };
        }

        const authHash = await getSapisidHash(${JSON.stringify(sapisid)}, 'https://www.youtube.com');
        if (!authHash) return { error: 'auth', message: 'Not logged in (SAPISID cookie missing)' };

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log into www.youtube.com in the browser page/profile the library controls.
  2. Point the automation at a persistent user-data-dir that retains the Google session.
  3. Verify the SAPISID cookie exists (DevTools → Application → Cookies → youtube.com).
  4. Re-login if the session expired (password change, security event) and retry.
Defensive patterns

Strategy: try-catch

Validate before calling

const cookies = await page.context().cookies('https://www.youtube.com');
if (!cookies.some(c => c.name === 'SAPISID')) {
  throw new Error('Log into youtube.com first: SAPISID cookie missing');
}

Try / catch

try {
  const history = await yt.history({ limit: 30 });
} catch (e) {
  if (e instanceof AuthRequiredError) {
    throw new Error('Open the automation browser and log into youtube.com, then retry');
  }
  throw e;
}

Prevention

When it happens

Trigger: Running `youtube history` with a browser profile/page that is not logged into YouTube, cookies cleared or expired, using a fresh automation profile without a Google session, or third-party-cookie blocking preventing cookie reads.

Common situations: CI/headless environments with a clean profile; logged out of Google in the automation browser; expired session after password change or security sign-out; connecting the scraper to the wrong user-data-dir without YouTube login.

Related errors


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