{"record":{"id":"d3278955a9bab858","repo":"emilk/egui","slug":"could-not-create-date-d32789","errorCode":null,"errorMessage":"Could not create Date","messagePattern":"Could not create Date","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/egui_extras/src/datepicker/popup.rs","lineNumber":22,"sourceCode":"\nuse super::{button::DatePickerButtonState, month_data};\n\nuse crate::{Column, Size, StripBuilder, TableBuilder};\n\n#[derive(Default, Clone)]\n#[cfg_attr(feature = \"serde\", derive(serde::Deserialize, serde::Serialize))]\nstruct DatePickerPopupState {\n    year: i16,\n    month: i8,\n    day: i8,\n    setup: bool,\n    year_scroll_needed: bool,\n}\n\nimpl DatePickerPopupState {\n    fn last_day_of_month(&self) -> i8 {\n        Date::new(self.year, self.month, 1)\n            .expect(\"Could not create Date\")\n            .days_in_month()\n    }\n}\n\npub(crate) struct DatePickerPopup<'a> {\n    pub selection: &'a mut Date,\n    pub button_id: Id,\n    pub combo_boxes: bool,\n    pub arrows: bool,\n    pub calendar: bool,\n    pub calendar_week: bool,\n    pub highlight_weekends: bool,\n    pub start_end_years: Option<core::ops::RangeInclusive<i16>>,\n    pub reverse_years: bool,\n    pub year_scroll_to: Option<i16>,\n}\n\nimpl DatePickerPopup<'_> {","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/emilk/egui/blob/441971a776322a482e371775219380eca812cfa9/crates/egui_extras/src/datepicker/popup.rs#L4-L40","documentation":"DatePickerPopupState::last_day_of_month calls Date::new(self.year, self.month, 1) and unwraps it with .expect(\"Could not create Date\"). The chrono-based Date constructor only accepts a month in 1..=12 (and a valid year), so if the popup state's month field has drifted outside that range the expect panics. The library treats this as an internal invariant: nothing outside the popup state machine should ever be able to set an out-of-range month.","triggerScenarios":"Calling last_day_of_month while popup_state.month is 0, negative, or > 12 — e.g. after custom code or a bug in month navigation decrements past January without wrapping the year, or a manually constructed DatePickerPopupState carries an invalid month.","commonSituations":"Custom date-picker wrappers that poke at popup_state.month/year directly instead of using the prev/next month buttons; month arithmetic implemented with 0-based months (JS/Python habit) fed into this 1-based API; deserializing persisted picker state from an old or corrupt format.","solutions":["Fix the month-navigation arithmetic so decrementing past month 1 wraps to month 12 and increments/decrements the year","Clamp or normalize month into 1..=12 before constructing DatePickerPopupState or before calling last_day_of_month","Replace the expect with graceful handling (match on the Result) and log the invalid state instead of panicking","Update egui_extras if this reproduces with plain next/prev month navigation — it may be a fixed upstream bug"],"exampleFix":"// before\nfn last_day_of_month(&self) -> i8 {\n    Date::new(self.year, self.month, 1)\n        .expect(\"Could not create Date\")\n        .days_in_month()\n}\n// after\nfn last_day_of_month(&self) -> i8 {\n    let month = self.month.clamp(1, 12);\n    Date::new(self.year, month, 1)\n        .unwrap_or_else(|e| panic!(\"invalid picker date {}/{}: {}\", self.year, month, e))\n        .days_in_month()\n}","handlingStrategy":"validation","validationCode":"assert!((1..=12).contains(&popup_state.month), \"invalid month {} for date picker state\", popup_state.month);","typeGuard":"fn valid_month(month: i32) -> bool { (1..=12).contains(&month) }","tryCatchPattern":null,"preventionTips":["Never set popup_state.month/year directly; use the picker's own navigation methods that wrap months","Remember egui's date picker months are 1-based, unlike JS/Python Date month APIs","Normalize persisted or deserialized picker state (clamp month to 1..=12) on load"],"tags":["date","panic","internal-state","egui"],"backgroundTag":"value-out-of-range","analyzedSha":"441971a776322a482e371775219380eca812cfa9","analyzedAt":"2026-09-12T04:29:21.500Z","contentChangedAt":"2026-09-12T04:29:21.500Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}