{"record":{"id":"aa1744d2b015c493","repo":"JuliusBrussee/caveman","slug":"days-must-be-an-integer-from-0-to-3660","errorCode":null,"errorMessage":"--days must be an integer from 0 to 3660","messagePattern":"--days must be an integer from 0 to 3660","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/cmd/caveman-proxy/stats.go","lineNumber":41,"sourceCode":"\t\tif seen[arg] {\n\t\t\treturn opts, false, \"\", fmt.Errorf(\"duplicate %s\", arg)\n\t\t}\n\t\tseen[arg] = true\n\t\tswitch arg {\n\t\tcase \"--report\", \"--json\":\n\t\tcase \"--write-report\":\n\t\t\twriteReport = true\n\t\tcase \"--days\", \"--provider\", \"--model\", \"--agent\", \"--auth\", \"--out\":\n\t\t\ti++\n\t\t\tif i >= len(args) || args[i] == \"\" || strings.HasPrefix(args[i], \"--\") || strings.ContainsAny(args[i], \"\\x00\\r\\n\") {\n\t\t\t\treturn opts, false, \"\", fmt.Errorf(\"%s requires a value\", arg)\n\t\t\t}\n\t\t\tvalue := args[i]\n\t\t\tswitch arg {\n\t\t\tcase \"--days\":\n\t\t\t\tdays, err := strconv.Atoi(value)\n\t\t\t\tif err != nil || days < 0 || days > 3660 {\n\t\t\t\t\treturn opts, false, \"\", fmt.Errorf(\"--days must be an integer from 0 to 3660\")\n\t\t\t\t}\n\t\t\t\topts.Days = days\n\t\t\tcase \"--provider\":\n\t\t\t\topts.Provider = value\n\t\t\tcase \"--model\":\n\t\t\t\topts.Model = value\n\t\t\tcase \"--agent\":\n\t\t\t\topts.Agent = value\n\t\t\tcase \"--auth\":\n\t\t\t\topts.AuthMode = value\n\t\t\tcase \"--out\":\n\t\t\t\tout, writeReport = value, true\n\t\t\t}\n\t\tdefault:\n\t\t\treturn opts, false, \"\", fmt.Errorf(\"unknown stats report option %s\", arg)\n\t\t}\n\t}\n\treturn opts, writeReport, out, nil","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/proxy/cmd/caveman-proxy/stats.go#L23-L59","documentation":"The --days option of the stats report command must parse as an integer between 0 and 3660 inclusive (proxy/cmd/caveman-proxy/stats.go:41). Any non-integer value or an out-of-range number is rejected with this fixed message, guarding StatsReportOptions.Days before it reaches the SQL time-window query.","triggerScenarios":"'stats --days week' (non-numeric); 'stats --days -1' or 'stats --days 9999' (out of the 0–3660 range).","commonSituations":"Passing a duration word or '30d' instead of a plain integer; a calculator slip producing a huge window; confusion with other CLIs that accept '30d' style durations.","solutions":["Pass a plain integer between 0 and 3660, e.g. --days 30","Convert '30d' style durations to bare numbers (--days 30)","Use 0 deliberately to mean an unbounded/today-only window per the tool's semantics, not a negative value"],"exampleFix":"// before\ncaveman-proxy stats --days 30d --report\n// after\ncaveman-proxy stats --days 30 --report","handlingStrategy":"validation","validationCode":"d, err := strconv.Atoi(raw)\nif err != nil || d < 0 || d > 3660 {\n    return fmt.Errorf(\"--days must be an integer from 0 to 3660\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass plain integers, never '30d' style durations","Clamp computed windows to 0..3660 before passing them","Document the max window (10 years) where the command is generated"],"tags":["cli","validation","value-out-of-range","stats"],"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"}