jackwener/OpenCLI · error · CommandExecutionError

Failed to fetch Watch Later — make sure you are logged into

Error message

Failed to fetch Watch Later — make sure you are logged into YouTube

What it means

Thrown when the in-browser script used by `youtube watch-later` returns null or a non-object, meaning the Watch Later playlist could not be extracted. Because the private Watch Later page requires an authenticated session, the message tells the user the most likely cause: they are not logged into YouTube in the browser session the CLI uses. The library throws this instead of silently returning an empty result so callers can distinguish auth failure from a genuinely empty playlist.

Source

Thrown at clis/youtube/watch-later.js:65

        let videos = extractVideos(listContents);

        let contItem = listContents[listContents.length - 1];
        while (videos.length < limit && contItem?.continuationItemRenderer && apiKey && context) {
          const token = contItem.continuationItemRenderer?.continuationEndpoint?.continuationCommand?.token;
          if (!token) break;
          const contData = await fetchBrowse(apiKey, { context, continuation: token });
          if (contData.error) break;
          const newItems = contData.onResponseReceivedActions?.[0]?.appendContinuationItemsAction?.continuationItems || [];
          if (!newItems.length) break;
          videos = videos.concat(extractVideos(newItems));
          contItem = newItems[newItems.length - 1];
        }

        return { title, stats, videos: videos.slice(0, limit) };
      })()
    `);
        if (!data || typeof data !== 'object') {
            throw new CommandExecutionError('Failed to fetch Watch Later — make sure you are logged into YouTube');
        }
        if (data.error) {
            throw new CommandExecutionError(String(data.error));
        }
        if (!data.videos?.length) {
            throw new EmptyResultError('youtube watch-later');
        }
        const statsStr = (data.stats || []).join(' | ');
        process.stderr.write(`${data.title}  ${statsStr}\n`);
        return data.videos;
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log into YouTube in the CLI's browser session, then re-run the command.
  2. Verify cookies are fresh — re-authenticate if the session expired.
  3. Run with a visible browser (not fully headless) once to see whether a consent or captcha page is blocking extraction.
  4. Update the CLI if YouTube changed the Watch Later page structure.

Example fix

// before (session without login)
$ opencli youtube watch-later
Error: Failed to fetch Watch Later — make sure you are logged into YouTube
// after
$ opencli youtube login   # or re-import fresh cookies
$ opencli youtube watch-later
Defensive patterns

Strategy: try-catch

Validate before calling

// Check session before invoking
const loggedIn = await run(['youtube', 'whoami']).catch(() => false);
if (!loggedIn) throw new Error('Login to YouTube before fetching Watch Later');

Type guard

const hasData = (d) => d !== null && typeof d === 'object';

Try / catch

try {
  const items = await run(['youtube', 'watch-later']);
} catch (e) {
  if (e.message.includes('logged into YouTube')) {
    await run(['youtube', 'login']); // re-authenticate, then retry once
  } else throw e;
}

Prevention

When it happens

Trigger: Running `youtube watch-later` when the browser session has no valid YouTube login, the page evaluation is blocked or returns undefined (bot check, consent wall, page layout change), or the evaluation script throws and the wrapper swallows it into null.

Common situations: Expired YouTube session cookies; running on a headless/CI machine where no one ever logged in; YouTube consent page intercepting navigation; IP-based bot detection preventing the playlist from rendering.

Related errors


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