{"record":{"id":"136402bbcee45459","repo":"jackwener/OpenCLI","slug":"youtube-history-limit-must-be-max-limit","errorCode":null,"errorMessage":"youtube history limit must be <= ${MAX_LIMIT}","messagePattern":"youtube history limit must be <= (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/youtube/history.js","lineNumber":29,"sourceCode":"} from '@jackwener/opencli/errors';\nimport {\n    prepareYoutubeApiPage,\n    readYoutubeSapisid,\n    SAPISID_HASH_FN,\n} from './utils.js';\n\nconst DEFAULT_LIMIT = 30;\nconst MAX_LIMIT = 200;\nconst MAX_PAGES = 20;\nconst REQUEST_TIMEOUT_SECONDS = 15;\n\nfunction normalizeLimit(value) {\n    const limit = Number(value ?? DEFAULT_LIMIT);\n    if (!Number.isInteger(limit) || limit <= 0) {\n        throw new ArgumentError('youtube history limit must be a positive integer');\n    }\n    if (limit > MAX_LIMIT) {\n        throw new ArgumentError(`youtube history limit must be <= ${MAX_LIMIT}`);\n    }\n    return limit;\n}\n\ncli({\n    site: 'youtube',\n    name: 'history',\n    access: 'read',\n    description: 'Get YouTube watch history',\n    domain: 'www.youtube.com',\n    strategy: Strategy.COOKIE,\n    args: [\n        { name: 'limit', type: 'int', default: DEFAULT_LIMIT, help: 'Max videos to return (default 30, max 200)' },\n    ],\n    columns: ['rank', 'title', 'channel', 'views', 'duration', 'url'],\n    func: async (page, kwargs) => {\n        const limit = normalizeLimit(kwargs.limit);\n        await prepareYoutubeApiPage(page);","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/youtube/history.js#L11-L47","documentation":"ArgumentError thrown by normalizeLimit when the `limit` argument exceeds MAX_LIMIT (200) for `youtube history`. The library caps pagination to at most 200 videos to bound scraping time (up to 20 pages of requests). Values must be integers in [1, 200].","triggerScenarios":"Calling `youtube history` with limit > 200 — e.g. --limit 500 or programmatic limit: 1000. The check runs after the positive-integer check, so 201+ valid integers trigger this exact branch.","commonSituations":"Users expecting unlimited history and asking for thousands of items; copying limits from other tools with higher caps; programmatically computing a limit without clamping to the documented max.","solutions":["Reduce limit to 200 or below.","Clamp programmatically: Math.min(Math.max(1, n), 200).","If more history is genuinely needed, call the command multiple times with pagination if supported.","Check the command's help text for the documented maximum."],"exampleFix":"// before\nawait yt.history({ limit: 1000 }); // ArgumentError: must be <= 200\n// after\nconst n = Math.min(Math.max(1, Number(reqLimit) || 30), 200);\nawait yt.history({ limit: n });","handlingStrategy":"validation","validationCode":"const MAX = 200;\nfunction clampLimit(v) {\n  const n = Number(v);\n  if (!Number.isInteger(n) || n <= 0) return 30;\n  return Math.min(n, MAX);\n}\nopts.limit = clampLimit(opts.limit);","typeGuard":"function withinCap(v) {\n  return typeof v === 'number' && Number.isInteger(v) && v >= 1 && v <= 200;\n}","tryCatchPattern":"try {\n  return await yt.history({ limit });\n} catch (e) {\n  if (e instanceof ArgumentError && /<= 200/.test(e.message)) {\n    return yt.history({ limit: 200 });\n  }\n  throw e;\n}","preventionTips":["Clamp user/config limits to 200 before calling.","Read the command help for the documented maximum.","Never pass unbounded page counts from generic pagination loops.","Centralize limit normalization in one helper."],"tags":["validation","argument-error","youtube","limits"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}