{"record":{"id":"1b5acc358d117bf0","repo":"influxdata/influxdb","slug":"invalid-month-0-expected-1-12","errorCode":null,"errorMessage":"invalid month {0}, expected 1-12","messagePattern":"invalid month (.+?), expected 1-12","errorType":"validation","errorClass":"YearMonthError","httpStatus":null,"severity":"warning","filePath":"influxdb3_write/src/lib.rs","lineNumber":427,"sourceCode":"        }\n    }\n}\n\n/// A year-month value in YYYY-MM format (e.g., \"2025-01\").\n///\n/// Used for organizing snapshot checkpoints by month. Stores year and month\n/// as integers for efficient comparison and sorting, while serializing to\n/// the standard \"YYYY-MM\" string format for backward compatibility.\n#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]\npub struct YearMonth {\n    year: u16,\n    month: u8,\n}\n\n/// Error type for invalid YearMonth values.\n#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]\npub enum YearMonthError {\n    #[error(\"invalid month {0}, expected 1-12\")]\n    InvalidMonth(u8),\n    #[error(\"invalid year-month format: {0}, expected YYYY-MM\")]\n    InvalidFormat(String),\n}\n\nimpl YearMonth {\n    /// Create a YearMonth from year and month without validation.\n    ///\n    /// # Safety\n    /// Use only when the values are known to be valid (e.g., from chrono).\n    /// In debug builds, panics if month is not in 1-12.\n    pub fn new_unchecked(year: u16, month: u8) -> Self {\n        debug_assert!((1..=12).contains(&month), \"month must be 1-12\");\n        Self { year, month }\n    }\n\n    /// Get the year component.\n    pub fn year(&self) -> u16 {","sourceCodeStart":409,"sourceCodeEnd":445,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_write/src/lib.rs#L409-L445","documentation":"YearMonthError::InvalidMonth is returned when constructing or validating a YearMonth with a month value outside 1–12 (e.g. 0 or 13). YearMonth represents a validated year+month pair used for retention/compaction windows. Validation is deliberate so downstream code can assume a valid calendar month.","triggerScenarios":"Calling YearMonth::new(year, month) or a parser with month > 12 or month == 0, e.g. from user-supplied retention period settings or computed month arithmetic that overflows December.","commonSituations":"Config files specifying retention_window in months with an out-of-range value; arithmetic like month+1 without wraparound; parsing API query parameters where a client sends 13 for a month.","solutions":["Clamp or validate month input to 1..=12 before constructing YearMonth","Fix off-by-one month arithmetic with proper wraparound (use year increments when month exceeds 12)","If parsing user input, surface a clear validation message before calling YearMonth","Check config for typos like month=13 or 0-based month values"],"exampleFix":"// before\nlet ym = YearMonth::new(2026, 13)?; // InvalidMonth(13)\n// after\nassert!((1..=12).contains(&month));\nlet ym = YearMonth::new(2026, month)?;","handlingStrategy":"validation","validationCode":"fn valid_month(m: u8) -> Result<u8, String> {\n    if (1..=12).contains(&m) { Ok(m) } else { Err(format!(\"month {} out of range 1-12\", m)) }\n}","typeGuard":"fn is_valid_month(m: u8) -> bool { (1..=12).contains(&m) }","tryCatchPattern":"match YearMonth::new(y, m) {\n    Err(YearMonthError::InvalidMonth(bad)) => {\n        eprintln!(\"month {} invalid; using current month\", bad);\n        YearMonth::current()\n    }\n    r => r?,\n}","preventionTips":["Clamp month values from config/CLI to 1..=12 at parse time","Use date libraries (chrono) for month arithmetic to get wraparound for free","Reject 0-based months from clients early with a clear message","Unit-test retention config parsing with boundary months (0, 1, 12, 13)"],"tags":["rust","validation","date"],"backgroundTag":"value-out-of-range","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}