{"record":{"id":"0dce3b99ac53c073","repo":"santifer/career-ops","slug":"limit-must-be-an-integer-from-1-to-100","errorCode":null,"errorMessage":"--limit must be an integer from 1 to 100","messagePattern":"--limit must be an integer from 1 to 100","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"company-funded.mjs","lineNumber":127,"sourceCode":"    dryRun: false,\n    json: false,\n    selfTest: false,\n    help: false,\n  };\n  for (let i = 0; i < argv.length; i++) {\n    const arg = argv[i];\n    if (arg === '--dry-run') opts.dryRun = true;\n    else if (arg === '--json') opts.json = true;\n    else if (arg === '--self-test') opts.selfTest = true;\n    else if (arg === '--help' || arg === '-h') opts.help = true;\n    else if (arg === '--limit') opts.limit = Number(argv[++i] || '');\n    else if (arg === '--months') opts.months = Number(argv[++i] || '');\n    else if (arg === '--sort') opts.sort = String(argv[++i] || '').trim().toLowerCase();\n    else if (arg === '--sources') opts.sources = parseSources(argv[++i] || '');\n    else throw new Error(`unknown option: ${arg}`);\n  }\n  if (!Number.isInteger(opts.limit) || opts.limit <= 0 || opts.limit > 100) {\n    throw new Error('--limit must be an integer from 1 to 100');\n  }\n  if (!Number.isInteger(opts.months) || opts.months <= 0 || opts.months > 120) {\n    throw new Error('--months must be an integer from 1 to 120');\n  }\n  if (!['date', 'score'].includes(opts.sort)) {\n    throw new Error('--sort must be date or score');\n  }\n  return opts;\n}\n\nfunction parseSources(value) {\n  const out = String(value || '')\n    .split(',')\n    .map((s) => normalizeSourceName(s.trim()))\n    .filter(Boolean);\n  const unique = [...new Set(out)];\n  const allowed = new Set(['techcrunch', 'prnewswire', 'guardian', 'hn']);\n  for (const source of unique) {","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/company-funded.mjs#L109-L145","documentation":"parseArgs validates `--limit` after the flag loop: it must be an integer (Number.isInteger), strictly positive, and at most 100. `--limit` is converted with Number(), so non-numeric text becomes NaN and fails the check, producing this error.","triggerScenarios":"`node company-funded.mjs --limit abc` (NaN), `--limit 0`, `--limit -5`, `--limit 500` (>100), `--limit 2.5` (not an integer), or `--limit` as the last argument (Number('') → NaN).","commonSituations":"Pasting a float or locale-formatted number; assuming the limit is unbounded; scripts parameterizing the limit from an unvalidated env var or CI input; forgetting the value after the flag.","solutions":["Pass an integer between 1 and 100, e.g. `--limit 50`.","Clamp or floor the value in the calling script before forwarding it.","Validate the source value (env var, config) before passing it as `--limit`.","Ensure `--limit` is not the final bare flag without a value."],"exampleFix":"// before\nnode company-funded.mjs --limit 500\n\n// after\nnode company-funded.mjs --limit 100","handlingStrategy":"validation","validationCode":"function validLimit(n) {\n  const v = Number(n);\n  return Number.isInteger(v) && v > 0 && v <= 100 ? v : null;\n}\n// pre-check: if (validLimit(rawLimit) === null) fail fast before spawning the script","typeGuard":"const isBoundedInt = (v, max) => Number.isInteger(v) && v > 0 && v <= max;","tryCatchPattern":"try {\n  run(['--limit', String(limit)]);\n} catch (e) {\n  if (e.message.includes('--limit must be')) {\n    console.warn('Clamping limit to 100 and retrying');\n    run(['--limit', '100']);\n  } else throw e;\n}","preventionTips":["Clamp limits in wrapper scripts before forwarding.","Parse CLI numbers as integers, never trust locale-formatted strings.","Validate env/config-sourced values at the boundary.","Always supply the value as a separate argv token after the flag."],"tags":["cli","validation","argument-parsing"],"backgroundTag":"value-out-of-range","analyzedSha":"aac998c7ed7248ea853b720ceeb1fdbeb322fc5d","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}