{"record":{"id":"bdfdbe036bd3b1e8","repo":"jackwener/OpenCLI","slug":"packagist-label-must-be-maxvalue","errorCode":null,"errorMessage":"packagist ${label} must be <= ${maxValue}","messagePattern":"packagist (.+?) must be <= (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/packagist/utils.js","lineNumber":27,"sourceCode":"const UA = 'opencli-packagist-adapter (+https://github.com/jackwener/opencli)';\n\n// Each segment of a Composer package name (`vendor` and `package`).\nconst SEGMENT = /^[a-z0-9]([_.-]?[a-z0-9]+)*$/;\n\nexport function requireString(value, label) {\n    const s = String(value ?? '').trim();\n    if (!s) throw new ArgumentError(`packagist ${label} cannot be empty`);\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(`packagist ${label} must be a positive integer`);\n    }\n    if (n > maxValue) {\n        throw new ArgumentError(`packagist ${label} must be <= ${maxValue}`);\n    }\n    return n;\n}\n\nexport function requirePackageName(value) {\n    const raw = String(value ?? '').trim().toLowerCase();\n    if (!raw) {\n        throw new ArgumentError('packagist package name is required (e.g. \"symfony/console\", \"monolog/monolog\")');\n    }\n    const slash = raw.indexOf('/');\n    if (slash <= 0 || slash === raw.length - 1) {\n        throw new ArgumentError(\n            `packagist package \"${value}\" must be \"<vendor>/<package>\"`,\n            'Both segments are required (Composer convention).',\n        );\n    }\n    const vendor = raw.slice(0, slash);\n    const pkg = raw.slice(slash + 1);","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/packagist/utils.js#L9-L45","documentation":"requireBoundedInt throws this ArgumentError when the value is a valid positive integer but exceeds the maxValue bound passed by the caller (e.g. a maximum page size for `limit`). It prevents abusive or accidentally huge requests to Packagist. The message includes the exact allowed maximum.","triggerScenarios":"Calling limit with a value above the configured max, e.g. requireBoundedInt(1000, 10, 100, 'limit') — 1000 > maxValue 100.","commonSituations":"User passes --limit 99999 thinking more is better; a script copies a limit from another API with a larger ceiling; a hardcoded constant exceeds the adapter's cap after a library update lowered maxValue.","solutions":["Lower the value so it is <= the maxValue reported in the message.","Clamp programmatically: Math.min(n, maxValue) before calling.","Read the adapter docs for the supported limit range and adjust your config.","Catch ArgumentError and retry with the maximum allowed value."],"exampleFix":"// before\nrun({ limit: 1000 }); // exceeds max\n\n// after\nrun({ limit: Math.min(Number(opts.limit), 100) });","handlingStrategy":"validation","validationCode":"const MAX_LIMIT = 100;\nfunction clampLimit(v) {\n  const n = Number(v);\n  return Math.min(Math.max(1, Math.floor(n) || 1), MAX_LIMIT);\n}","typeGuard":"const isIntWithin = (v, max) => Number.isInteger(v) && v > 0 && v <= max;","tryCatchPattern":"try {\n  await run({ limit });\n} catch (e) {\n  const m = /must be <= (\\d+)/.exec(e.message);\n  if (e instanceof ArgumentError && m) {\n    return run({ limit: Number(m[1]) });\n  }\n  throw e;\n}","preventionTips":["Clamp user-supplied limits against the documented maximum before calling.","Parse the maxValue from the error message and retry at the boundary if acceptable.","Keep one shared constant for the limit cap across your tooling.","Note the cap in CLI help/config comments."],"tags":["argument-validation","out-of-range","limit","packagist"],"backgroundTag":"value-out-of-range","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}