{"record":{"id":"76d5706aa12617b7","repo":"jackwener/OpenCLI","slug":"label-must-be-maxvalue-76d570","errorCode":null,"errorMessage":"${label} must be <= ${maxValue}","messagePattern":"(.+?) must be <= (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/weread/book-search.js","lineNumber":31,"sourceCode":"        .replace(/&#(\\d+);/g, (_, n) => String.fromCharCode(Number(n)))\n        .replace(/&nbsp;/g, ' ')\n        .replace(/&amp;/g, '&')\n        .replace(/&quot;/g, '\"')\n        .trim();\n}\n\nfunction normalizeSearchText(value) {\n    return String(value || '').replace(/\\s+/g, ' ').trim();\n}\n\nfunction normalizePositiveInteger(value, defaultValue, label, maxValue) {\n    const raw = value ?? defaultValue;\n    const n = Number(raw);\n    if (!Number.isInteger(n) || n <= 0) {\n        throw new ArgumentError(`${label} must be a positive integer`);\n    }\n    if (maxValue != null && n > maxValue) {\n        throw new ArgumentError(`${label} must be <= ${maxValue}`);\n    }\n    return n;\n}\n\nfunction parseOptionalFiniteNumber(value) {\n    if (value == null || value === '')\n        return null;\n    const n = Number(value);\n    return Number.isFinite(n) ? n : null;\n}\n\nfunction parseHasMore(value) {\n    if (value === true || value === 1 || value === '1')\n        return true;\n    if (value === false || value === 0 || value === '0')\n        return false;\n    return null;\n}","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weread/book-search.js#L13-L49","documentation":"normalizePositiveInteger also enforces an optional upper bound (maxValue); if the parsed integer exceeds it, the library throws ArgumentError with the label and the max. This guards options like limit or fragment-size against absurd values that would break downstream requests or pagination.","triggerScenarios":"Passing --limit 1000 or --fragment-size 99999 when the command's normalizePositiveInteger call passes a maxValue cap, or --book-rank greater than the allowed maximum configured by the command.","commonSituations":"Users assume 'bigger is better' for limits; copy-pasted settings from another tool exceed this tool's caps; scripts use hardcoded large batch sizes.","solutions":["Lower the option value to at most the stated maxValue in the message","Check the command help/default to learn the allowed maximum","Clamp the value in the calling script: Math.min(value, MAX)","If the cap seems too restrictive, open an issue or patch normalizePositiveInteger's call site instead of fighting it at runtime"],"exampleFix":"// before\nweread book-search --query zen --limit 500\n// after\nweread book-search --query zen --limit 20","handlingStrategy":"validation","validationCode":"function ensureInRange(v, name, max) {\n  const n = ensurePositiveInt(v, name);\n  if (max != null && n > max) throw new RangeError(`${name} must be <= ${max}, got ${n}`);\n  return n;\n}\nensureInRange(opts.limit, 'limit', 50);","typeGuard":"const withinMax = (v, max) => Number.isInteger(Number(v)) && Number(v) > 0 && Number(v) <= max;","tryCatchPattern":"try {\n  await runCommand(['book-search', '--query', q, '--limit', String(limit)]);\n} catch (e) {\n  if (e instanceof ArgumentError && /must be <= /.test(e.message)) {\n    const max = Number(e.message.match(/<= (\\d+)/)?.[1] ?? Infinity);\n    console.error(`Reduce the option to at most ${max}.`);\n  } else throw e;\n}","preventionTips":["Clamp user-supplied limits with Math.min against the documented max before invoking the CLI","Read command help to learn caps instead of assuming unlimited values","Centralize max constants in wrapper scripts so they stay in sync with the CLI"],"tags":["validation","cli-arguments","argument-error"],"backgroundTag":"value-out-of-range","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}