{"record":{"id":"df69c4489e0b1de9","repo":"jackwener/OpenCLI","slug":"limit-must-be-an-integer-between-1-and-max-df69c4","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/guazi/utils.js","lineNumber":84,"sourceCode":"    throw new ArgumentError('city', `unknown city '${cityArg}'. pass a Guazi city code or one of: ${names}`);\n}\n\n/** Normalize a clue id: a bare number or a /car-detail/c<id>.htm(l) URL. */\nexport function normalizeClueId(rawInput) {\n    const raw = String(rawInput || '').trim();\n    if (!raw) throw new ArgumentError('clue_id must be a non-empty value');\n    const m = raw.match(/car-detail\\/c(\\d+)/) || raw.match(/^c?(\\d+)$/);\n    if (!m) {\n        throw new ArgumentError(`'${rawInput}' does not look like a guazi clue id (a number, or a /car-detail/c<id>.html URL)`);\n    }\n    return m[1];\n}\n\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\nexport function clean(s) {\n    return String(s == null ? '' : s).replace(/\\s+/g, ' ').trim();\n}\n\nexport function requireText(value, label) {\n    const text = clean(value);\n    if (!text) throw new CommandExecutionError(`${label} did not include a stable text value.`);\n    return text;\n}\n\nexport function requireStableId(value, label) {\n    const id = String(value ?? '').trim();\n    if (!/^\\d+$/.test(id)) throw new CommandExecutionError(`${label} did not include a stable numeric id.`);\n    return id;","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/guazi/utils.js#L66-L102","documentation":"requireLimit validates the user-supplied --limit, coercing strings to numbers and defaulting when empty; it throws this ArgumentError when the value is not an integer in the range [1, max] (max is 40 when called with default 20 from browse). Non-numeric strings, decimals, zero, negatives, and values above max all land here.","triggerScenarios":"'guazi browse --limit abc' (NaN), --limit 10.5 (not an integer), --limit 0 or --limit -3 (out of range), --limit 100 (above max 40), --limit '  25  ' is fine because it trims, but 'twenty' is not.","commonSituations":"Copy-pasting '25 rows' into the flag; setting limit in a config file as a string with a unit ('20 items'); intending page size vs total and passing 1000 expecting all rows.","solutions":["Pass a plain integer between 1 and 40, e.g. --limit 20.","Remove any unit text or thousand separators from the value.","If you need more rows than max, raise the max argument at the requireLimit call site (clis/guazi/browse.js passes 20 default, 40 max).","Omit --limit entirely to use the default of 20."],"exampleFix":"// before\nguazi browse --city bj --limit 100\n// after\nguazi browse --city bj --limit 40","handlingStrategy":"validation","validationCode":"function isValidLimit(v, max = 40) {\n  if (v == null || v === '') return true; // default applies\n  const n = Number(String(v).trim());\n  return Number.isInteger(n) && n >= 1 && n <= max;\n}","typeGuard":"function isLimit(v): v is number {\n  const n = typeof v === 'number' ? v : Number(v);\n  return Number.isInteger(n) && n >= 1 && n <= 40;\n}","tryCatchPattern":"try {\n  const rows = await guaziBrowse({ city, limit });\n} catch (e) {\n  if (/limit must be an integer/.test(e.message)) {\n    console.error(`--limit must be an integer 1-40, got: ${limit}`);\n    process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Pass plain integers without units or separators","Clamp user input: Math.min(Math.max(1, n), 40)","Remember the max is 40 for browse","Omit the flag to use the default 20"],"tags":["argument-validation","cli","range-check"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}