{"record":{"id":"71b0ab31ba1ca4da","repo":"jackwener/OpenCLI","slug":"weread-official-label-must-be-max","errorCode":null,"errorMessage":"weread-official: ${label} must be <= ${max}","messagePattern":"weread-official: (.+?) must be <= (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/weread-official/utils.js","lineNumber":275,"sourceCode":"}\n\nexport function requirePositiveInt(value, label, { defaultValue, max } = {}) {\n    if (value === undefined || value === null || value === '') {\n        if (defaultValue === undefined) {\n            throw new ArgumentError(`weread-official: ${label} is required`);\n        }\n        return defaultValue;\n    }\n    const text = String(value).trim();\n    if (!/^\\d+$/.test(text)) {\n        throw new ArgumentError(`weread-official: ${label} must be a positive integer`);\n    }\n    const n = Number(text);\n    if (!Number.isSafeInteger(n) || n < 1) {\n        throw new ArgumentError(`weread-official: ${label} must be a positive integer`);\n    }\n    if (max !== undefined && n > max) {\n        throw new ArgumentError(`weread-official: ${label} must be <= ${max}`);\n    }\n    return n;\n}\n\nexport function requireChoice(value, choices, label, defaultValue) {\n    const text = String(value ?? defaultValue ?? '').trim();\n    if (!choices.includes(text)) {\n        throw new ArgumentError(`weread-official: ${label} must be one of: ${choices.join(', ')}`);\n    }\n    return text;\n}\n\n// ── Empty-result helper ────────────────────────────────────────────────────\n\n/** Throw EmptyResultError with a stable command label. */\nexport function emptyResult(command, hint) {\n    throw new EmptyResultError(`weread-official ${command}`, hint);\n}","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weread-official/utils.js#L257-L293","documentation":"requirePositiveInt accepts an optional { max } bound; when provided and the parsed integer exceeds it, the value is rejected with this message showing the cap. It protects downstream WeRead API calls from unreasonable page sizes / counts.","triggerScenarios":"Passing --count 500 to a command whose call site invokes requirePositiveInt(value, label, { max: 100 }) — any n > max throws.","commonSituations":"Users assuming 'bigger is better' for limits; old scripts written before a server-side/API cap was introduced; confusing per-page vs total limits.","solutions":["Lower the value to at most the stated maximum, e.g. --count 100 when the message says 'must be <= 100'.","Read the command's --help to learn the accepted range for the option.","Paginate instead: request max repeatedly with offset/page advancement to reach a larger total.","Update scripts to clamp: Math.min(requested, max) before invoking."],"exampleFix":"// before\ncli(['listNotebooks', '--count', '1000']);\n// after\ncli(['listNotebooks', '--count', '100']);","handlingStrategy":"validation","validationCode":"const MAX = 100; // mirror the limit enforced by the command\nconst n = Number(value);\nif (!Number.isSafeInteger(n) || n < 1 || n > MAX) throw new Error(`count must be between 1 and ${MAX}`);","typeGuard":"function isWithinRange(v, max) { return Number.isSafeInteger(v) && v >= 1 && v <= max; }","tryCatchPattern":"try {\n  await cli.run(['listNotebooks', '--count', requested]);\n} catch (e) {\n  const m = /must be <= (\\d+)$/.exec(e.message || '');\n  if (m) {\n    await cli.run(['listNotebooks', '--count', m[1]]); // retry at the cap\n  } else throw e;\n}","preventionTips":["Parse the max out of the error message and clamp automatically in wrappers.","Paginate with repeated max-size requests rather than one oversized request.","Document limits in team scripts/configs so users don't guess."],"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-29T12:17:43.993Z"}