{"record":{"id":"82887d0cb1c57974","repo":"jackwener/OpenCLI","slug":"label-must-be-range-got-parsed","errorCode":null,"errorMessage":"${label} must be ${range}, got ${parsed}","messagePattern":"(.+?) must be (.+?), got (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/linkedin/search.js","lineNumber":82,"sourceCode":"        if (!mapped)\n            throw new ArgumentError(`Unsupported ${label}: ${value}`);\n        return mapped;\n    });\n    return [...new Set(resolved)];\n}\nfunction normalizeWhitespace(value) {\n    return String(value ?? '').replace(/\\s+/g, ' ').trim();\n}\nfunction parseIntegerArg(value, label, fallback, min, max = Infinity) {\n    if (value === undefined || value === null || value === '')\n        return fallback;\n    const parsed = Number(value);\n    if (!Number.isFinite(parsed) || !Number.isInteger(parsed)) {\n        throw new ArgumentError(`${label} must be an integer, got ${JSON.stringify(value)}`);\n    }\n    if (parsed < min || parsed > max) {\n        const range = Number.isFinite(max) ? `between ${min} and ${max}` : `at least ${min}`;\n        throw new ArgumentError(`${label} must be ${range}, got ${parsed}`);\n    }\n    return parsed;\n}\nfunction decodeLinkedinRedirect(url) {\n    if (!url)\n        return '';\n    try {\n        const parsed = new URL(url);\n        if (parsed.pathname === '/redir/redirect/') {\n            return parsed.searchParams.get('url') || url;\n        }\n    }\n    catch { }\n    return url;\n}\nfunction buildVoyagerSearchQuery(input) {\n    const hasFilters = input.companyIds.length ||\n        input.experienceLevels.length ||","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linkedin/search.js#L64-L100","documentation":"After confirming the value is an integer, parseIntegerArg range-checks it against [min, max]; out-of-range values throw ArgumentError(`${label} must be ${range}, got ${parsed}`). The range text says 'between min and max' when max is finite, or 'at least min' when max is Infinity, so limit/start arguments stay within what the LinkedIn search API and CLI accept.","triggerScenarios":"Calling a search command with --limit or --start below its minimum (e.g. 0 or negative) or above its maximum (e.g. --limit 500 where the max is smaller), or --start negative for pagination offset.","commonSituations":"'Fetch everything' scripts that set an oversized limit; off-by-one pagination producing start=-1; hardcoding limit=0 expecting 'no cap' instead of the documented default; raising limits after a CLI version lowered the max.","solutions":["Clamp limit/start into the documented range for that command (check its --help for min/max).","Use the argument's default by omitting it, and paginate by advancing start instead of raising limit.","Fix negative offsets by flooring start at 0.","Handle range errors programmatically by parsing the min/max out of the message before retrying."],"exampleFix":"// before\nnode cli.js linkedin search-people --limit 1000   # above max\n// ArgumentError: limit must be between 1 and 100, got 1000\n// after\nnode cli.js linkedin search-people --limit 100 --start 0\nnode cli.js linkedin search-people --limit 100 --start 100  # paginate instead","handlingStrategy":"validation","validationCode":"limit = Math.max(minLimit, Math.min(maxLimit, Number(limit) || defaultLimit)); start = Math.max(0, Number(start) || 0);","typeGuard":"function inRange(n, min, max = Infinity){ return Number.isInteger(n) && n >= min && n <= max; }","tryCatchPattern":"try { await search({limit, start}) } catch (e) { const m = /must be (?:between (\\d+) and (\\d+)|at least (\\d+))/.exec(e.message); if (m) { /* clamp and retry once */ } else throw e; }","preventionTips":["Clamp limit/start to the documented min/max before every call.","Paginate by advancing start rather than inflating limit.","Floor negative offsets at 0.","Re-check ranges after CLI upgrades that may change limits."],"tags":["argument-error","range-validation","linkedin","pagination"],"backgroundTag":"argument-out-of-range","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}