{"record":{"id":"bd69dbe2ffca4643","repo":"jackwener/OpenCLI","slug":"string-data-error-bd69db","errorCode":null,"errorMessage":"String(data.error)","messagePattern":"String\\(data\\.error\\)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/youtube/playlist.js","lineNumber":89,"sourceCode":"        while (videos.length < limit && contItem?.continuationItemRenderer) {\n          const token = contItem.continuationItemRenderer?.continuationEndpoint?.continuationCommand?.token;\n          if (!token) break;\n          const contData = await fetchBrowse(apiKey, { context, continuation: token });\n          if (contData.error) break;\n          const newItems = contData.onResponseReceivedActions?.[0]?.appendContinuationItemsAction?.continuationItems || [];\n          if (!newItems.length) break;\n          videos = videos.concat(extractVideos(newItems));\n          contItem = newItems[newItems.length - 1];\n        }\n\n        return { title, channelName, stats, videos: videos.slice(0, limit) };\n      })()\n    `);\n        if (!data || typeof data !== 'object') {\n            throw new CommandExecutionError('Failed to fetch playlist data');\n        }\n        if (data.error) {\n            throw new CommandExecutionError(String(data.error));\n        }\n        if (!data.videos?.length) {\n            throw new EmptyResultError('youtube playlist');\n        }\n        const statsStr = (data.stats || []).join(' | ');\n        process.stderr.write(`${data.title}  [${data.channelName}]  ${statsStr}\\n`);\n        return data.videos;\n    },\n});\n","sourceCodeStart":71,"sourceCodeEnd":99,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/youtube/playlist.js#L71-L99","documentation":"CommandExecutionError wrapping the raw error string returned inside the scrape result object (data.error). The playlist extraction succeeded structurally but reported a domain-specific failure — e.g. YouTube showed an error/alert box instead of playlist data — and the library surfaces that string verbatim.","triggerScenarios":"The in-page script returns {error: '<description>'} — typically ytInitialData missing, a 'Playlist does not exist' / 'unavailable' alert, or a consent/bot-check page detected during extraction.","commonSituations":"Deleted or private playlist IDs, region-locked playlists, YouTube UI/ytInitialData schema changes breaking extraction, or age/consent interstitials in headless sessions.","solutions":["Check the error string — 'playlist unavailable' means the ID is wrong/private/deleted","Verify the playlist opens in a normal browser","Login to YouTube in the CLI profile if consent/age gating is indicated","Update the CLI package to pick up extraction fixes for new YouTube markup"],"exampleFix":"// before\nopencli youtube playlist PL_DELETED  // 'The playlist does not exist.'\n// after\nopencli youtube playlist PL_EXISTING_PUBLIC_ID","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  const videos = await run('youtube playlist', [id]);\n} catch (e) {\n  if (/does not exist|unavailable|private/i.test(e.message)) {\n    console.error(`Playlist ${id} is gone or private: ${e.message}`);\n  } else throw e;\n}","preventionTips":["Handle the surfaced error string as domain truth (deleted/private/unavailable)","Check playlist existence periodically in automations over long-lived IDs","Re-login if consent/age gating is indicated in the message","Update the CLI package when extraction breaks after YouTube updates"],"tags":["youtube","playlist","scraping","command-execution"],"backgroundTag":"page-scrape-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}