{"record":{"id":"e15fbe66d532dda0","repo":"JuliusBrussee/caveman","slug":"days-must-be-an-integer-from-1-to-3660","errorCode":null,"errorMessage":"--days must be an integer from 1 to 3660","messagePattern":"--days must be an integer from 1 to 3660","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/stats-cli.ts","lineNumber":44,"sourceCode":"  plain: boolean;\n  open: boolean;\n  out?: string;\n  filters: string[];\n};\n\nexport function parseStatsOptions(argv: string[]): StatsCLIOptions {\n  const result: StatsCLIOptions = { json: false, plain: false, open: false, filters: [] };\n  const seen = new Set<string>();\n  const valueFlags = new Set([\"--days\", \"--provider\", \"--model\", \"--agent\", \"--auth\", \"--out\"]);\n  for (let i = 0; i < argv.length; i++) {\n    const arg = argv[i]!;\n    if (seen.has(arg)) throw new Error(`duplicate ${arg}`);\n    seen.add(arg);\n    if (valueFlags.has(arg)) {\n      const value = argv[++i];\n      if (!value || value.startsWith(\"--\") || /[\\u0000-\\u001f\\u007f]/u.test(value)) throw new Error(`${arg} requires a value`);\n      if (arg === \"--days\" && (!/^\\d+$/u.test(value) || Number(value) < 1 || Number(value) > 3660)) {\n        throw new Error(\"--days must be an integer from 1 to 3660\");\n      }\n      if (arg === \"--out\") result.out = value;\n      else result.filters.push(arg, value);\n    } else if (arg === \"--json\") result.json = true;\n    else if (arg === \"--plain\" || arg === \"--no-open\") result.plain = true;\n    else if (arg === \"--open\") result.open = true;\n    else if (arg === \"--all-time\") result.filters.push(\"--days\", \"0\");\n    else throw new Error(`unknown option ${arg}`);\n  }\n  if (seen.has(\"--days\") && seen.has(\"--all-time\")) throw new Error(\"choose --days or --all-time\");\n  if (result.plain && result.open) throw new Error(\"choose --plain or --open\");\n  if (result.json && result.open) throw new Error(\"--json cannot open a browser\");\n  return result;\n}\n\ntype StatsMetrics = {\n  requests: number;\n  successful_requests: number;","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/cli/src/stats-cli.ts#L26-L62","documentation":"The --days flag must be a decimal integer between 1 and 3660 inclusive; anything else (non-numeric, zero, negative, floats, or > 3660) throws. Use --all-time instead of a huge --days value for unbounded windows.","triggerScenarios":"`--days 0`, `--days -5`, `--days 4000`, `--days 7.5`, `--days week`, or a value with units like `--days 30d`.","commonSituations":"Trying to request 'all time' with --days 0 (the correct flag is --all-time); copying a duration with a unit suffix from another tool's CLI; scripts computing a window that overflows 3660 (10 years).","solutions":["Pass a plain integer 1–3660: `--days 30`","Use `--all-time` instead of a very large or zero --days value","Clamp/compute the value in the calling script before invoking, e.g. Math.min(Math.max(days,1),3660)"],"exampleFix":"// before\nmyapp stats --days 0\n// after\nmyapp stats --all-time","handlingStrategy":"validation","validationCode":"if (raw !== undefined && !/^\\d+$/u.test(raw)) throw new Error(\"--days must be an integer\");\nconst days = Number(raw);\nif (days < 1 || days > 3660) throw new Error(\"--days must be 1..3660\");","typeGuard":null,"tryCatchPattern":"try {\n  const opts = parseStatsOptions([\"--days\", raw]);\n} catch (e) {\n  if (e.message === \"--days must be an integer from 1 to 3660\") {\n    console.error(\"pass an integer 1-3660, or use --all-time\"); process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Never use --days 0 for 'all time' — use --all-time","Strip unit suffixes (30d) before passing","Clamp computed day windows to the 1..3660 range"],"tags":["cli","validation"],"backgroundTag":"value-out-of-range","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}