jackwener/OpenCLI · error · CommandExecutionError
String(data.error)
Error message
String(data.error)
What it means
This error surfaces the dynamic `data.error` value returned by the Watch Later extraction script as a CommandExecutionError. Unlike the login-failure guard, the payload here IS an object, but it carries an explicit `error` field produced by the in-page script (e.g. navigation failure, unexpected page state). The message text is not fixed — it is whatever the extraction script reported, stringified.
Source
Thrown at clis/youtube/watch-later.js:68
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
- Read the surfaced message — it names the concrete in-page failure the script detected.
- Retry after a short delay if the cause looks transient (network, 5xx).
- Re-check login/consent state in the CLI browser session.
- Update the CLI if the message indicates a page-structure mismatch.
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate payload before use; error field presence is the signal
if (result && typeof result === 'object' && result.error) {
throw new Error(`Extraction reported: ${result.error}`);
} Type guard
const isExtractionError = (d) => d !== null && typeof d === 'object' && typeof d.error === 'string' && d.error.length > 0;
Try / catch
try {
const videos = await run(['youtube', 'watch-later']);
} catch (e) {
// message is the dynamic in-page error — log it verbatim for diagnosis
console.error('watch-later extraction error:', e.message);
if (isTransient(e.message)) await sleep(5000), retry();
else throw e;
} Prevention
- Log the surfaced message verbatim — it names the concrete in-page failure
- Add retry-with-backoff for transient causes (5xx, network)
- Keep cookies and CLI version current
- Don't blanket-swallow: distinguish this from login and empty-result errors
When it happens
Trigger: Running `youtube watch-later` when the injected evaluation script detects an error condition and returns { error: '...' } — for example the Watch Later page failed to load, a selector found nothing and the script flagged it, or YouTube returned an error interstitial.
Common situations: Transient YouTube server errors (500s) during page load; region or consent redirects landing on a different page; the playlist page rendering in an unexpected locale/layout; network interruption mid-navigation.
Related errors
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/4f24c8584108b442.
Report an issue: GitHub.