BloopAI/vibe-kanban · error
date overflow for digest schedule
Error message
date overflow for digest schedule
What it means
`checked_add_days` returns None when adding the days would overflow the date range (NaiveDate max is ~year 262143). The code expects this never happens, panicking with "date overflow for digest schedule" otherwise. It is a guard against scheduling arithmetic at the edge of chrono's representable date range.
Source
Thrown at crates/remote/src/digest/task.rs:151
Err(error) => {
error!(error = %error, "Failed to acquire notification digest lock");
None
}
}
}
fn next_run_at(now: DateTime<Utc>, run_hour_utc: u32) -> DateTime<Utc> {
let today = now.date_naive();
let today_run = today
.and_hms_opt(run_hour_utc, 0, 0)
.expect("validated digest hour");
let next_naive = if now.hour() < run_hour_utc {
today_run
} else {
today
.checked_add_days(Days::new(1))
.expect("date overflow for digest schedule")
.and_hms_opt(run_hour_utc, 0, 0)
.expect("validated digest hour")
};
DateTime::from_naive_utc_and_offset(next_naive, Utc)
}
View on GitHub (pinned to 4deb7eca8f)
Solutions
- Treat as effectively impossible but fail gracefully: replace expect with unwrap_or_else(|| now + chrono::Duration::hours(24))
- Use checked arithmetic end-to-end and propagate a Result to digest_loop so a bad clock doesn't crash the process
- Log and reset the schedule if system time looks implausible (e.g. year > 9999)
Example fix
// before
.checked_add_days(Days::new(1)).expect("date overflow for digest schedule")
// after
.checked_add_days(Days::new(1))
.unwrap_or_else(|| now.date_naive().succ_opt().unwrap_or(now.date_naive())) Defensive patterns
Strategy: fallback
Validate before calling
fn plausible_now(now: DateTime<Utc>) -> bool { now.year() >= 1970 && now.year() < 9999 } Try / catch
match std::panic::catch_unwind(|| next_run_at(now, hour)) { Ok(t) => t, Err(_) => now + chrono::Duration::hours(24) } Prevention
- Use checked arithmetic throughout and propagate a Result
- Sanity-check system clock plausibility before scheduling
- Log schedule computation failures instead of panicking in a long-running loop
When it happens
Trigger: `digest_loop` calls `next_run_at` with a `now` (Utc::now()) whose date is near NaiveDate::MAX so adding 1 day overflows and checked_add_days returns None.
Common situations: Practically unreachable in normal operation; could appear with a wildly incorrect system clock (year far beyond 262000), clock skew/failure producing sentinel dates, or tests passing synthetic far-future timestamps.
Related errors
- validated digest hour
- Default profiles v3 JSON is invalid
- request_id called for unsupported request variant
- handled non-session commands earlier
- Raw stream should only have Stdout/Stderr/Finished
AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29).
Data as JSON: /api/errors/12a00d1f2ccd87a4.
Report an issue: GitHub.