santifer/career-ops · error · Error

--months must be an integer from 1 to 120

Error message

--months must be an integer from 1 to 120

What it means

CLI argument validation in company-funded.mjs's parseArgs: the --months value (coerced with Number()) failed the integer range check — it is NaN (missing or non-numeric argument), a non-integer, or outside 1-120. The input at fault is the token immediately after --months on the command line.

Solutions

  1. Pass an integer from 1 to 120, e.g. `--months 12`.
  2. Convert other duration units to months before invoking (days/30, weeks/4.33 — floored).
  3. Clamp in wrapper scripts: Math.min(120, Math.max(1, value)).
  4. Ensure the value follows the flag as a separate argv token.

Example fix

// before
node company-funded.mjs --months 365

// after
node company-funded.mjs --months 12
Defensive patterns

Strategy: validation

Validate before calling

function validMonths(n) {
  const v = Number(n);
  return Number.isInteger(v) && v > 0 && v <= 120 ? v : null;
}
// if (validMonths(cfg.lookbackMonths) === null) throw new Error('lookbackMonths must be 1-120');

Type guard

const isMonthsInRange = (v) => Number.isInteger(v) && v >= 1 && v <= 120;

Try / catch

try {
  run(['--months', String(months)]);
} catch (e) {
  if (e.message.includes('--months must be')) {
    console.warn('Clamping months to 120 and retrying');
    run(['--months', '120']);
  } else throw e;
}

Prevention

When it happens

Trigger: `--months 0`, `--months 200`, `--months "6 months"` (NaN), `--months 1.5`, or `--months` with no following value (Number('') → NaN).

Common situations: Requesting a lookback window longer than the supported 10 years; passing a human-readable duration string; unit confusion (passing days or weeks where months are expected); CI variables with empty values.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16). Data as JSON: /api/errors/6f60a9a6ccd0c947. Report an issue: GitHub.

Appendix: source

Thrown at company-funded.mjs:130

    help: false,
  };
  for (let i = 0; i < argv.length; i++) {
    const arg = argv[i];
    if (arg === '--dry-run') opts.dryRun = true;
    else if (arg === '--json') opts.json = true;
    else if (arg === '--self-test') opts.selfTest = true;
    else if (arg === '--help' || arg === '-h') opts.help = true;
    else if (arg === '--limit') opts.limit = Number(argv[++i] || '');
    else if (arg === '--months') opts.months = Number(argv[++i] || '');
    else if (arg === '--sort') opts.sort = String(argv[++i] || '').trim().toLowerCase();
    else if (arg === '--sources') opts.sources = parseSources(argv[++i] || '');
    else throw new Error(`unknown option: ${arg}`);
  }
  if (!Number.isInteger(opts.limit) || opts.limit <= 0 || opts.limit > 100) {
    throw new Error('--limit must be an integer from 1 to 100');
  }
  if (!Number.isInteger(opts.months) || opts.months <= 0 || opts.months > 120) {
    throw new Error('--months must be an integer from 1 to 120');
  }
  if (!['date', 'score'].includes(opts.sort)) {
    throw new Error('--sort must be date or score');
  }
  return opts;
}

function parseSources(value) {
  const out = String(value || '')
    .split(',')
    .map((s) => normalizeSourceName(s.trim()))
    .filter(Boolean);
  const unique = [...new Set(out)];
  const allowed = new Set(['techcrunch', 'prnewswire', 'guardian', 'hn']);
  for (const source of unique) {
    if (!allowed.has(source)) throw new Error(`unknown source in --sources: ${source}`);
  }
  return unique.length ? unique : [...DEFAULT_SOURCES];

View on GitHub (pinned to aac998c7ed)