{"record":{"id":"8ce15f3a6ced3c43","repo":"jackwener/OpenCLI","slug":"string-payload-error-8ce15f","errorCode":null,"errorMessage":"String(payload.error)","messagePattern":"String\\(payload\\.error\\)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/youtube/video.js","lineNumber":21,"sourceCode":" */\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',\n    name: 'video',\n    access: 'read',\n    description: 'Get YouTube video metadata (title, views, description, etc.)',","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/youtube/video.js#L3-L39","documentation":"CommandExecutionError thrown when the extracted video payload itself carries an error field. The page-side extraction script detected a failure (e.g. the video page reported an error or a fetch failed) and returned it as { error: ... }; the library converts that string into a thrown CommandExecutionError.","triggerScenarios":"payload.error is truthy — e.g. the in-page script captured 'HTTP 404' for a missing video, a playability failure it chose to surface as an error, or a page-side exception message.","commonSituations":"Deleted/private/geoblocked videos; network or HTTP failures while the page script fetched metadata; YouTube page changes causing the in-page script to fail; rate limiting or bot challenges.","solutions":["Use the thrown message (String(payload.error)) to identify the concrete page-side failure (e.g. HTTP status).","Verify the video ID/URL is valid and publicly accessible in a normal browser.","Handle restricted videos (private, deleted, region-locked) explicitly before retrying.","Retry with backoff if the error suggests a transient HTTP/network failure; update the library if the page structure changed."],"exampleFix":"// before\nconst info = await video(url); // throws CommandExecutionError\n// after\ntry {\n  const info = await video(url);\n} catch (e) {\n  if (e.name === 'CommandExecutionError') console.error('video fetch error:', e.message);\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const info = await video(url);\n} catch (e) {\n  if (e.name === 'CommandExecutionError') {\n    const detail = e.message;\n    if (/HTTP 4\\d\\d/.test(detail)) {\n      return handleUnavailableVideo(url, detail);\n    }\n    return retryWithBackoff(() => video(url));\n  }\n  throw e;\n}","preventionTips":["Classify e.message: 4xx means the video is unavailable (don't retry), 5xx/transient means retry.","Verify video IDs/URLs point to public, existing videos before extraction.","Handle region locks, age restrictions, and consent interstitials explicitly.","Retry transient network errors with backoff; keep the extractor current with YouTube changes."],"tags":["youtube","browser","metadata","page-error"],"backgroundTag":"page-evaluation-error","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}