{"record":{"id":"42ffda57e6ead02d","repo":"jackwener/OpenCLI","slug":"page-must-be-between-articles-min-page-and","errorCode":null,"errorMessage":"--page must be between ${ARTICLES_MIN_PAGE} and ${ARTICLES_MAX_PAGE}, got ${parsed}","messagePattern":"--page must be between (.+?) and (.+?), got (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/toutiao/utils.js","lineNumber":20,"sourceCode":" * Shared helpers for the toutiao adapter.\n */\nimport { ArgumentError, CommandExecutionError } from '@jackwener/opencli/errors';\n\nconst ARTICLES_MIN_PAGE = 1;\nconst ARTICLES_MAX_PAGE = 4;\nconst HOT_MIN_LIMIT = 1;\nconst HOT_MAX_LIMIT = 50;\nconst RECOMMEND_MIN_LIMIT = 1;\nconst RECOMMEND_MAX_LIMIT = 50;\n\nexport function parseArticlesPage(raw, fallback = 1) {\n    if (raw === undefined || raw === null || raw === '') return fallback;\n    const parsed = Number(raw);\n    if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) {\n        throw new ArgumentError(`--page must be an integer between ${ARTICLES_MIN_PAGE} and ${ARTICLES_MAX_PAGE}, got ${JSON.stringify(raw)}`);\n    }\n    if (parsed < ARTICLES_MIN_PAGE || parsed > ARTICLES_MAX_PAGE) {\n        throw new ArgumentError(`--page must be between ${ARTICLES_MIN_PAGE} and ${ARTICLES_MAX_PAGE}, got ${parsed}`);\n    }\n    return parsed;\n}\n\nexport function parseRecommendLimit(raw, fallback = 20) {\n    if (raw === undefined || raw === null || raw === '') return fallback;\n    const parsed = Number(raw);\n    if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) {\n        throw new ArgumentError(`--limit must be an integer between ${RECOMMEND_MIN_LIMIT} and ${RECOMMEND_MAX_LIMIT}, got ${JSON.stringify(raw)}`);\n    }\n    if (parsed < RECOMMEND_MIN_LIMIT || parsed > RECOMMEND_MAX_LIMIT) {\n        throw new ArgumentError(`--limit must be between ${RECOMMEND_MIN_LIMIT} and ${RECOMMEND_MAX_LIMIT}, got ${parsed}`);\n    }\n    return parsed;\n}\n\nexport function parseRecommendCategory(raw, fallback = '__all__') {\n    if (raw === undefined || raw === null || raw === '') return fallback;","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/toutiao/utils.js#L2-L38","documentation":"This ArgumentError is thrown by parseArticlesPage when --page is an integer but outside the allowed [ARTICLES_MIN_PAGE, ARTICLES_MAX_PAGE] range. It is a range guard preventing nonsense pagination values from being sent upstream.","triggerScenarios":"Running an article command with `--page 0`, `--page -3`, or `--page 99999999` — any integer below ARTICLES_MIN_PAGE or above ARTICLES_MAX_PAGE.","commonSituations":"Off-by-one assumptions that pages start at 0; brute-force pagination loops without a bound check; scripts generating page numbers from unbounded computations.","solutions":["Use a page value within the documented range, starting at ARTICLES_MIN_PAGE (typically 1).","Clamp the value: Math.min(ARTICLES_MAX_PAGE, Math.max(ARTICLES_MIN_PAGE, n)) before passing.","Stop pagination loops when the range error is raised — it means you have gone past the last valid page.","Check the CLI help/docs for the current min/max constants."],"exampleFix":"// before\nfor (let p = 0; p < 1000; p++) await articles({ page: p });\n// after\nconst MAX = 100; // ARTICLES_MAX_PAGE\nfor (let p = 1; p <= MAX; p++) await articles({ page: p });","handlingStrategy":"validation","validationCode":"const ARTICLES_MIN_PAGE = 1, ARTICLES_MAX_PAGE = 100; // match library constants\nfunction clampPage(n) {\n  return Math.min(ARTICLES_MAX_PAGE, Math.max(ARTICLES_MIN_PAGE, n));\n}","typeGuard":"function isPageInRange(n) {\n  return Number.isInteger(n) && n >= ARTICLES_MIN_PAGE && n <= ARTICLES_MAX_PAGE;\n}","tryCatchPattern":"try {\n  await articles({ page: p });\n} catch (e) {\n  if (e instanceof ArgumentError && e.message.startsWith('--page must be between')) {\n    console.error('Page out of range; clamping to valid range.');\n    return articles({ page: clampPage(p) });\n  }\n  throw e;\n}","preventionTips":["Clamp page numbers to [min, max] before passing.","Remember pages start at 1, not 0.","Stop pagination loops on this error — you have passed the last valid page.","Check the constants in clis/toutiao/utils.js for current bounds."],"tags":["argument-validation","cli","range-check"],"backgroundTag":"argument-out-of-range","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}