emilk/egui · error

Could not create Date

Error message

Could not create Date

What it means

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.

Solutions

  1. Fix the month-navigation arithmetic so decrementing past month 1 wraps to month 12 and increments/decrements the year
  2. Clamp or normalize month into 1..=12 before constructing DatePickerPopupState or before calling last_day_of_month
  3. Replace the expect with graceful handling (match on the Result) and log the invalid state instead of panicking
  4. Update egui_extras if this reproduces with plain next/prev month navigation — it may be a fixed upstream bug

Example fix

// before
fn last_day_of_month(&self) -> i8 {
    Date::new(self.year, self.month, 1)
        .expect("Could not create Date")
        .days_in_month()
}
// after
fn last_day_of_month(&self) -> i8 {
    let month = self.month.clamp(1, 12);
    Date::new(self.year, month, 1)
        .unwrap_or_else(|e| panic!("invalid picker date {}/{}: {}", self.year, month, e))
        .days_in_month()
}
Defensive patterns

Strategy: validation

Validate before calling

assert!((1..=12).contains(&popup_state.month), "invalid month {} for date picker state", popup_state.month);

Type guard

fn valid_month(month: i32) -> bool { (1..=12).contains(&month) }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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 emilk/egui@441971a776 (2026-09-12). Data as JSON: /api/errors/d3278955a9bab858. Report an issue: GitHub.

Appendix: source

Thrown at crates/egui_extras/src/datepicker/popup.rs:22

use super::{button::DatePickerButtonState, month_data};

use crate::{Column, Size, StripBuilder, TableBuilder};

#[derive(Default, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
struct DatePickerPopupState {
    year: i16,
    month: i8,
    day: i8,
    setup: bool,
    year_scroll_needed: bool,
}

impl DatePickerPopupState {
    fn last_day_of_month(&self) -> i8 {
        Date::new(self.year, self.month, 1)
            .expect("Could not create Date")
            .days_in_month()
    }
}

pub(crate) struct DatePickerPopup<'a> {
    pub selection: &'a mut Date,
    pub button_id: Id,
    pub combo_boxes: bool,
    pub arrows: bool,
    pub calendar: bool,
    pub calendar_week: bool,
    pub highlight_weekends: bool,
    pub start_end_years: Option<core::ops::RangeInclusive<i16>>,
    pub reverse_years: bool,
    pub year_scroll_to: Option<i16>,
}

impl DatePickerPopup<'_> {

View on GitHub (pinned to 441971a776)