{"record":{"id":"7d488c9f50eee09e","repo":"jackwener/OpenCLI","slug":"youtube-history-limit-must-be-a-positive-integer","errorCode":null,"errorMessage":"youtube history limit must be a positive integer","messagePattern":"youtube history limit must be a positive integer","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/youtube/history.js","lineNumber":26,"sourceCode":"    CommandExecutionError,\n    EmptyResultError,\n    TimeoutError,\n} 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'],","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/youtube/history.js#L8-L44","documentation":"ArgumentError thrown by normalizeLimit when the `limit` argument to `youtube history` is not a positive integer. The library validates up front (Number.isInteger && > 0) before any page work, so invalid input fails fast. Acceptable values are integers from 1 to MAX_LIMIT (200).","triggerScenarios":"Passing limit as 0, a negative number, a non-integer (e.g. 12.5), or a non-numeric string like 'abc' or '' — anything where Number(value) is not a positive integer. Note '' coerces to 0 and '30' coerces to 30.","commonSituations":"CLI users typing `--limit 0` or `--limit -5`; programmatic callers passing a string like 'twenty' or a float from config; passing null explicitly (null ?? DEFAULT means default applies, but 0 does not).","solutions":["Pass a positive integer for limit (1–200).","Omit limit entirely to use the default (30).","Coerce/validate before calling: Number.isInteger(Number(limit)) && Number(limit) > 0.","If a float sneaks in from config, round it explicitly first."],"exampleFix":"// before\nawait yt.history({ limit: 0 }); // ArgumentError\n// after\nawait yt.history({ limit: 50 }); // or omit limit for default 30","handlingStrategy":"validation","validationCode":"function validLimit(v) {\n  const n = Number(v);\n  return Number.isInteger(n) && n > 0 && n <= 200;\n}\nif (!validLimit(opts.limit)) throw new Error('limit must be an integer 1-200');","typeGuard":"function isPositiveInt(v) {\n  return typeof v === 'number' && Number.isInteger(v) && v > 0;\n}","tryCatchPattern":"try {\n  return await yt.history({ limit });\n} catch (e) {\n  if (e instanceof ArgumentError) {\n    return yt.history({}); // fall back to default limit\n  }\n  throw e;\n}","preventionTips":["Always pass integers, never strings or floats, for limit.","Omit limit to use the default of 30.","Validate with Number.isInteger before calling.","Remember Number('') is 0 — sanitize config-provided values."],"tags":["validation","argument-error","youtube","input-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}