{"record":{"id":"e091f78a1855186f","repo":"jackwener/OpenCLI","slug":"youtube-watch-later","errorCode":null,"errorMessage":"youtube watch-later","messagePattern":"youtube watch-later","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/youtube/watch-later.js","lineNumber":71,"sourceCode":"          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, stats, videos: videos.slice(0, limit) };\n      })()\n    `);\n        if (!data || typeof data !== 'object') {\n            throw new CommandExecutionError('Failed to fetch Watch Later — make sure you are logged into YouTube');\n        }\n        if (data.error) {\n            throw new CommandExecutionError(String(data.error));\n        }\n        if (!data.videos?.length) {\n            throw new EmptyResultError('youtube watch-later');\n        }\n        const statsStr = (data.stats || []).join(' | ');\n        process.stderr.write(`${data.title}  ${statsStr}\\n`);\n        return data.videos;\n    },\n});\n","sourceCodeStart":53,"sourceCodeEnd":78,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/youtube/watch-later.js#L53-L78","documentation":"An EmptyResultError with the command name 'youtube watch-later' as its message, thrown when the Watch Later fetch succeeded (authenticated, no error field) but the parsed `videos` array is empty or missing. The library treats a logged-in-but-zero-videos playlist as a distinct condition so callers can handle 'no data' separately from auth or extraction failures.","triggerScenarios":"Running `youtube watch-later` (with or without --limit) when the authenticated session's Watch Later list is genuinely empty, or when the extraction found the page but its video-selector matched nothing due to a layout change.","commonSituations":"A fresh account with nothing saved to Watch Later; user recently cleared their Watch Later list; YouTube DOM change breaking the video selector so all rows are missed.","solutions":["Confirm in a browser that the account's Watch Later list actually has videos.","Add videos to Watch Later if the list is legitimately empty.","If videos exist in the browser but the CLI returns this, update the CLI — the selector likely no longer matches.","Catch EmptyResultError explicitly in scripts to treat it as 'no data' rather than a hard failure."],"exampleFix":"// before\nconst videos = await cli.run(['youtube', 'watch-later']);\n// after\ntry {\n  const videos = await cli.run(['youtube', 'watch-later']);\n} catch (e) {\n  if (e instanceof EmptyResultError) return [];\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"// Cannot validate remotely beforehand; guard the consumer instead\nconst safeVideos = Array.isArray(videos) ? videos : [];","typeGuard":"const isNonEmptyList = (v) => Array.isArray(v) && v.length > 0;","tryCatchPattern":"try {\n  const videos = await run(['youtube', 'watch-later']);\n} catch (e) {\n  if (e.name === 'EmptyResultError' || e.message === 'youtube watch-later') return [];\n  throw e;\n}","preventionTips":["Catch EmptyResultError explicitly and treat it as 'no data'","Check the account's Watch Later contents in a browser if unexpected","Keep the CLI updated in case a selector change hides existing videos","Return [] instead of crashing in pipelines that tolerate empty input"],"tags":["youtube","empty-result","scraping"],"backgroundTag":"empty-result","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}