{"record":{"id":"d2a26516bdfe1316","repo":"jackwener/OpenCLI","slug":"label-must-be-an-integer-between-1-and-maxi","errorCode":null,"errorMessage":"--${label} must be an integer between 1 and ${maximum}","messagePattern":"--(.+?) must be an integer between 1 and (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/xiaoyuzhou/history.js","lineNumber":20,"sourceCode":"import { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';\nimport { loadXiaoyuzhouCredentials, requestXiaoyuzhouJson } from './auth.js';\n\nconst DEFAULT_LIMIT = 20;\nconst MAX_LIMIT = 5000;\nconst DEFAULT_MAX_PAGES = 500;\nconst HARD_MAX_PAGES = 1000;\nconst HISTORY_ENDPOINT = '/v1/episode-played/list-history';\nconst PROGRESS_ENDPOINT = '/v1/playback-progress/list';\nconst XIAOYUZHOU_ID = /^[0-9a-f]{24}$/i;\n\nfunction isRecord(value) {\n    return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction positiveInteger(value, label, maximum) {\n    const parsed = Number(value);\n    if (!Number.isInteger(parsed) || parsed < 1 || parsed > maximum) {\n        throw new ArgumentError(`--${label} must be an integer between 1 and ${maximum}`);\n    }\n    return parsed;\n}\n\nfunction requiredId(value, label) {\n    if (typeof value !== 'string' || !XIAOYUZHOU_ID.test(value)) {\n        throw new CommandExecutionError(`Xiaoyuzhou history returned an invalid ${label}`);\n    }\n    return value.toLowerCase();\n}\n\nfunction requiredString(value, label) {\n    if (typeof value !== 'string' || !value.trim()) {\n        throw new CommandExecutionError(`Xiaoyuzhou history returned an invalid ${label}`);\n    }\n    return value.trim();\n}\n","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaoyuzhou/history.js#L2-L38","documentation":"This ArgumentError is thrown by the positiveInteger validator in clis/xiaoyuzhou/history.js when a user-supplied numeric CLI option (--limit or --max-pages) is not an integer between 1 and its allowed maximum (5000 for limit, 1000 for max-pages). The CLI validates these before making any network requests, so it is purely an input problem, not an API problem.","triggerScenarios":"Running `xiaoyuzhou history --limit 0`, `--limit abc`, `--limit 5001`, `--max-pages 0`, `--max-pages 1001`, or passing a fractional value like `--limit 2.5`. Values are coerced with Number(), so numeric strings are accepted but non-numeric strings, NaN, fractions, zero, negatives, and values above the max all throw.","commonSituations":"Scripting the CLI with an empty or misparsed shell variable (e.g. --limit \"\" becomes NaN); copying a max from docs of a different tool; trying to fetch more than 5000 rows with --limit instead of using --all; passing --max-pages too low and expecting it to be clamped rather than rejected.","solutions":["Pass an integer between 1 and 5000 for --limit, or use --all (which ignores --limit) to fetch the full history.","Use --max-pages between 1 and 1000; the default 500 is usually sufficient.","Fix the shell variable feeding the option (quote/default it, e.g. LIMIT=${LIMIT:-20}) so it is non-empty and numeric.","If you need more rows than the caps allow, paginate by re-running with a cursor or request a higher limit in the library config rather than forcing the CLI cap."],"exampleFix":"// before\n$ xiaoyuzhou history --limit 10000\nArgumentError: --limit must be an integer between 1 and 5000\n// after\n$ xiaoyuzhou history --limit 5000 --max-pages 1000\n# or to fetch everything:\n$ xiaoyuzhou history --all","handlingStrategy":"validation","validationCode":"function isValidPositiveInt(v, max) { const n = Number(v); return Number.isInteger(n) && n >= 1 && n <= max; }\nif (!isValidPositiveInt(process.argv.limit, 5000)) throw new Error('--limit must be 1..5000');\nif (!isValidPositiveInt(process.argv.maxPages, 1000)) throw new Error('--max-pages must be 1..1000');","typeGuard":"function isPositiveInteger(v, max) { return Number.isInteger(Number(v)) && Number(v) >= 1 && Number(v) <= max; }","tryCatchPattern":"try { await cli.run(['xiaoyuzhou', 'history', '--limit', String(limit)]); } catch (e) { if (e.name === 'ArgumentError') { console.error(`Bad option: ${e.message}`); process.exitCode = 2; } else throw e; }","preventionTips":["Validate numeric CLI args with Number.isInteger before invoking the CLI.","Default shell variables (LIMIT=${LIMIT:-20}) so empty values never reach the CLI.","Remember caps: limit <= 5000, max-pages <= 1000; use --all for full exports.","Never pass fractional or string-typed numbers; coerce with Number() first."],"tags":["cli","argument-validation","input-error"],"backgroundTag":"invalid-cli-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}