{"record":{"id":"459dd7afa3cd3fbe","repo":"jackwener/OpenCLI","slug":"limit-must-be-an-integer-between-1-and-max-459dd7","errorCode":null,"errorMessage":"limit must be an integer between 1 and ${max}","messagePattern":"limit must be an integer between 1 and (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/dongchedi/utils.js","lineNumber":166,"sourceCode":" */\nexport function normalizeSeriesId(rawInput) {\n    const raw = String(rawInput || '').trim();\n    if (!raw) throw new ArgumentError('series_id must be a non-empty value');\n    const m = raw.match(/series\\/(\\d+)/) || raw.match(/^(\\d+)$/);\n    if (!m) {\n        throw new ArgumentError(\n            `'${rawInput}' does not look like a dongchedi series id (a number, or a /auto/series/<id> URL)`,\n        );\n    }\n    return m[1];\n}\n\n/** Validate an integer limit in [1, max]. */\nexport function requireLimit(value, def, max) {\n    const raw = value == null || value === '' ? def : value;\n    const n = typeof raw === 'number' ? raw : Number(String(raw).trim());\n    if (!Number.isInteger(n) || n < 1 || n > max) {\n        throw new ArgumentError(`limit must be an integer between 1 and ${max}`);\n    }\n    return n;\n}\n\n/** Collapse whitespace and trim; returns '' for nullish. */\nexport function clean(s) {\n    return String(s == null ? '' : s).replace(/\\s+/g, ' ').trim();\n}\n\n/** Truncate long review text for table display, keeping it on one line. */\nexport function snippet(s, max = 180) {\n    const t = clean(s);\n    return t.length > max ? `${t.slice(0, max)}…` : t;\n}\n","sourceCodeStart":148,"sourceCodeEnd":181,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/dongchedi/utils.js#L148-L181","documentation":"requireLimit validates that a pagination limit is an integer within [1, max], defaulting nullish input to def. It throws ArgumentError for non-integers (decimals, non-numeric strings, NaN) and out-of-range values, so downstream queries never request 0 or huge page sizes.","triggerScenarios":"limit='10.5' or 'abc' (NaN), limit=0, negative numbers, limit greater than the endpoint's max, or a string with stray characters after Number() coercion.","commonSituations":"Parsing a CLI --limit flag that was given 'all' or 'max'; a config file with a float; an off-by-one attempt to 'fetch everything' with 0 or Infinity.","solutions":["Pass an integer between 1 and the documented max, e.g. limit=20","Omit the limit entirely to use the default (def)","If you want all items, call repeatedly paginating instead of setting an unbounded limit"],"exampleFix":"// before\nloadDoubanSubjectPhotos(page, id, { limit: 'all' });\n// after\nloadDoubanSubjectPhotos(page, id, { limit: 120 }); // or omit for default","handlingStrategy":"validation","validationCode":"const n = Number(value);\nif (value != null && value !== '' && (!Number.isInteger(n) || n < 1 || n > max)) {\n  throw new Error(`limit must be an integer in [1, ${max}]`);\n}","typeGuard":"function isValidLimit(v, max) { const n = Number(v); return Number.isInteger(n) && n >= 1 && n <= max; }","tryCatchPattern":"try { await list({ limit }); } catch (e) { if (e.name === 'ArgumentError') { limit = undefined; /* fall back to default */ } else throw e; }","preventionTips":["Clamp user input: Math.min(Math.max(1, parsed), max)","Reject non-numeric strings like 'all' before calling","Omit limit to use the library default"],"tags":["argument-error","validation","pagination","limit"],"backgroundTag":"invalid-parameter-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}