{"record":{"id":"43b4059ff7a8524a","repo":"jackwener/OpenCLI","slug":"failed-to-fetch-playlist-data","errorCode":null,"errorMessage":"Failed to fetch playlist data","messagePattern":"Failed to fetch playlist data","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/youtube/playlist.js","lineNumber":86,"sourceCode":"        let videos = extractVideos(listContents);\n\n        let contItem = listContents[listContents.length - 1];\n        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":68,"sourceCodeEnd":99,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/youtube/playlist.js#L68-L99","documentation":"CommandExecutionError thrown when the youtube playlist scrape's page.evaluate returns nothing usable — data is null, undefined, or not an object — meaning the in-page extraction script failed to produce its result object rather than returning a structured error. The library throws it instead of crashing on undefined property access.","triggerScenarios":"page.evaluate returns null/undefined/non-object: the playlist page failed to load, ytInitialData was absent, the script threw before returning and the harness swallowed it, or navigation hit a bot-check/consent page.","commonSituations":"Invalid or deleted playlist ID, private playlist, YouTube consent/cookie wall in a fresh profile, anti-bot interstitial, or network failure during page load.","solutions":["Verify the playlist URL/ID is valid, public, and still exists","Re-run — transient page-load failures are common","Log into YouTube in the profile to bypass consent walls","Update the CLI if YouTube's page structure changed"],"exampleFix":"// before\nopencli youtube playlist PL_BAD_ID  // null data\n// after\nopencli youtube playlist PL_VALID_PUBLIC_ID","handlingStrategy":"validation","validationCode":"// ensure the playlist exists/public before scraping\nconst res = await fetch(`https://www.youtube.com/playlist?list=${id}`, { method: 'HEAD' });\nif (!res.ok) throw new Error(`Playlist ${id} unreachable (HTTP ${res.status})`);","typeGuard":"const isScrapeResult = (d) => d !== null && typeof d === 'object' && !Array.isArray(d);","tryCatchPattern":"try {\n  const videos = await run('youtube playlist', [id]);\n} catch (e) {\n  if (/Failed to fetch playlist data/i.test(e.message)) {\n    console.error('Scrape returned no data — verify the playlist ID and login state');\n  } else throw e;\n}","preventionTips":["Validate playlist IDs (start with PL, UU, etc.) before calling","Test playlist visibility in a normal browser","Retry once on transient failures","Keep profile logged in to avoid consent/bot walls","Update the CLI when YouTube markup changes"],"tags":["youtube","scraping","playlist","command-execution"],"backgroundTag":"page-scrape-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}