jackwener/OpenCLI · error · CommandExecutionError
Failed to extract video metadata from page
Error message
Failed to extract video metadata from page
What it means
CommandExecutionError thrown by requireVideoPayload when the browser result, after unwrapBrowserResult, is not a usable object (null, non-object, or array). The library uses this to signal that the page-side video metadata extraction returned nothing usable, rather than returning partial or invalid data to the caller.
Source
Thrown at clis/youtube/video.js:18
/**
* YouTube video metadata — fetch watch HTML and parse bootstrap data without opening the watch UI.
*/
import { cli, Strategy } from '@jackwener/opencli/registry';
import { extractJsonAssignmentFromHtml, parseVideoId, prepareYoutubeApiPage } from './utils.js';
import { CommandExecutionError } from '@jackwener/opencli/errors';
function unwrapBrowserResult(value) {
if (value && typeof value === 'object' && 'session' in value && 'data' in value) {
return value.data;
}
return value;
}
function requireVideoPayload(value) {
const payload = unwrapBrowserResult(value);
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
throw new CommandExecutionError('Failed to extract video metadata from page');
}
if (payload.error) {
throw new CommandExecutionError(String(payload.error));
}
if (typeof payload.playabilityStatus !== 'string') {
throw new CommandExecutionError('YouTube video metadata is missing playabilityStatus');
}
if (typeof payload.playabilityReason !== 'string') {
throw new CommandExecutionError('YouTube video metadata is missing playabilityReason');
}
if (typeof payload.membersOnly !== 'boolean') {
throw new CommandExecutionError('YouTube video metadata is missing membersOnly');
}
return payload;
}
cli({
site: 'youtube',View on GitHub (pinned to 49907e53dc)
Solutions
- Log the raw browser result before calling the command to see what the page evaluation actually returned.
- Ensure the video page loaded fully before extraction (use prepareYoutubeApiPage / wait for ytcfg and player data).
- Retry the extraction — transient navigation/serialization failures often succeed on a second attempt.
- Check the target URL parses to a valid videoId; invalid URLs can lead the page script to return null metadata.
- Update the library if YouTube changed page structure, breaking the extraction script.
Defensive patterns
Strategy: type-guard
Validate before calling
const raw = await getPageVideoPayload(page);
if (raw == null || typeof raw !== 'object' || Array.isArray(raw)) {
throw new Error('Extraction returned no usable payload');
} Type guard
function isVideoPayload(v) {
return v != null && typeof v === 'object' && !Array.isArray(v);
} Try / catch
try {
const info = await video(url);
} catch (e) {
if (e.name === 'CommandExecutionError' && /extract video metadata/.test(e.message)) {
return retryExtraction(url, 1);
}
throw e;
} Prevention
- Ensure the video watch page is fully loaded before running the extraction script.
- Log the raw browser result to distinguish null results from malformed payloads.
- Validate videoId/URL before extraction; retry transient navigation failures.
- Keep the extraction script updated with YouTube DOM/player-response changes.
When it happens
Trigger: page.evaluate for video metadata resolved to null/undefined/a primitive/an array — e.g. the extraction script crashed in a way that returned null, or the browser result wrapper unwrapped to an unexpected type.
Common situations: Navigation or serialization failure inside the page so evaluate resolved null; extraction run before the watch page loaded; a malformed URL leading the in-page script to bail out; YouTube page changes breaking the extraction script entirely.
Related errors
- String(payload.error)
- result.message || 'Failed to remove like'
- result.message || 'Failed to unsubscribe'
- YouTube video metadata is missing playabilityStatus
- YouTube video metadata is missing playabilityReason
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/c5d57b84ba39b670.
Report an issue: GitHub.