{"record":{"id":"c01ea14cbf9af9aa","repo":"jackwener/OpenCLI","slug":"endoflife-label-must-be-maxvalue","errorCode":null,"errorMessage":"`endoflife ${label} must be <= ${maxValue}`","messagePattern":"`endoflife (.+?) must be <= (.+?)`","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/endoflife/utils.js","lineNumber":37,"sourceCode":"        );\n    }\n    if (!PRODUCT.test(s)) {\n        throw new ArgumentError(\n            `endoflife product \"${value}\" is not a valid endoflife.date slug`,\n            'Slugs are lowercase ASCII letters/digits/\"._-\", e.g. \"nodejs\", \"python\", \"ubuntu\".',\n        );\n    }\n    return s;\n}\n\nexport function requireBoundedInt(value, defaultValue, maxValue, label = 'limit') {\n    const raw = value ?? defaultValue;\n    const n = typeof raw === 'number' ? raw : Number(raw);\n    if (!Number.isInteger(n) || n <= 0) {\n        throw new ArgumentError(`endoflife ${label} must be a positive integer`);\n    }\n    if (n > maxValue) {\n        throw new ArgumentError(`endoflife ${label} must be <= ${maxValue}`);\n    }\n    return n;\n}\n\nexport async function eolFetch(url, label) {\n    let resp;\n    try {\n        resp = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' } });\n    }\n    catch (err) {\n        throw new CommandExecutionError(\n            `${label} request failed: ${err?.message ?? err}`,\n            'Check that endoflife.date is reachable from this network.',\n        );\n    }\n    if (resp.status === 404) {\n        throw new EmptyResultError(label, `endoflife.date returned 404 for ${url}.`);\n    }","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/endoflife/utils.js#L19-L55","documentation":"requireBoundedInt validates a numeric CLI option (e.g. a limit) against a hard upper bound. After confirming the value is a positive integer, it throws ArgumentError when the value exceeds the configured maximum. This guards against nonsensical or abusive inputs that would produce oversized requests to endoflife.date.","triggerScenarios":"Calling any command whose option flows through requireBoundedInt (e.g. a --limit flag) with an integer greater than the maxValue passed by the adapter, such as limit=50 when maxValue=20.","commonSituations":"Passing a larger page size than the CLI allows; copy-pasting defaults from another tool; scripting with a variable that was scaled up; assuming there is no cap on the limit option.","solutions":["Lower the option value to a positive integer <= the maxValue shown in the message","Check the CLI help/docs for the documented maximum for that option","Use the default value by omitting the option entirely","If you legitimately need more results, paginate by calling the command repeatedly"],"exampleFix":"// before\n$ opencli endoflife cycles nodejs --limit 100\nError: endoflife limit must be <= 20\n// after\n$ opencli endoflife cycles nodejs --limit 20","handlingStrategy":"validation","validationCode":"function isBoundedInt(v, max) {\n  const n = typeof v === 'number' ? v : Number(v);\n  return Number.isInteger(n) && n > 0 && n <= max ? n : null;\n}\nconst limit = isBoundedInt(opts.limit, 20) ?? 10; // clamp/replace before calling","typeGuard":"const isBoundedPositiveInt = (v, max) => {\n  const n = typeof v === 'number' ? v : Number(v);\n  return Number.isInteger(n) && n > 0 && n <= max;\n};","tryCatchPattern":null,"preventionTips":["Clamp or default the option before passing it to the command","Consult CLI help for documented maximums of numeric options","Validate numeric flags at config-load time in scripts","Avoid hand-editing limit values without checking bounds"],"tags":["validation","argument-error","cli-input"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}