{"record":{"id":"c5d57b84ba39b670","repo":"jackwener/OpenCLI","slug":"failed-to-extract-video-metadata-from-page","errorCode":null,"errorMessage":"Failed to extract video metadata from page","messagePattern":"Failed to extract video metadata from page","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/youtube/video.js","lineNumber":18,"sourceCode":"/**\n * YouTube video metadata — fetch watch HTML and parse bootstrap data without opening the watch UI.\n */\nimport { cli, Strategy } from '@jackwener/opencli/registry';\nimport { extractJsonAssignmentFromHtml, parseVideoId, prepareYoutubeApiPage } from './utils.js';\nimport { CommandExecutionError } from '@jackwener/opencli/errors';\n\nfunction unwrapBrowserResult(value) {\n    if (value && typeof value === 'object' && 'session' in value && 'data' in value) {\n        return value.data;\n    }\n    return value;\n}\n\nfunction requireVideoPayload(value) {\n    const payload = unwrapBrowserResult(value);\n    if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {\n        throw new CommandExecutionError('Failed to extract video metadata from page');\n    }\n    if (payload.error) {\n        throw new CommandExecutionError(String(payload.error));\n    }\n    if (typeof payload.playabilityStatus !== 'string') {\n        throw new CommandExecutionError('YouTube video metadata is missing playabilityStatus');\n    }\n    if (typeof payload.playabilityReason !== 'string') {\n        throw new CommandExecutionError('YouTube video metadata is missing playabilityReason');\n    }\n    if (typeof payload.membersOnly !== 'boolean') {\n        throw new CommandExecutionError('YouTube video metadata is missing membersOnly');\n    }\n    return payload;\n}\n\ncli({\n    site: 'youtube',","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/youtube/video.js#L1-L36","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"const raw = await getPageVideoPayload(page);\nif (raw == null || typeof raw !== 'object' || Array.isArray(raw)) {\n  throw new Error('Extraction returned no usable payload');\n}","typeGuard":"function isVideoPayload(v) {\n  return v != null && typeof v === 'object' && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  const info = await video(url);\n} catch (e) {\n  if (e.name === 'CommandExecutionError' && /extract video metadata/.test(e.message)) {\n    return retryExtraction(url, 1);\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["youtube","browser","metadata","null-result"],"backgroundTag":"browser-result-unwrap-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}