embassy-rs/embassy · error
overflow when adding durations
Error message
overflow when adding durations
What it means
embassy-time's `Duration` implements `Add` via `checked_add`; if the resulting tick count exceeds the internal representation (i64 microseconds / u64 ticks), `.expect("overflow when adding durations")` panics. It matches std's documented behavior that `Duration + Duration` panics on overflow.
Solutions
- Use `checked_add` and handle `None` yourself (clamp to `Duration::MAX` or return an error)
- Clamp inputs: `a.saturating_add(b)` if available, or `a.checked_add(b).unwrap_or(Duration::MAX)`
- Validate user-supplied timeout magnitudes before arithmetic
Example fix
// before let total = a + b; // panics on overflow // after let total = a.checked_add(b).unwrap_or(Duration::MAX);
Defensive patterns
Strategy: try-catch
Validate before calling
fn safe_add(a: embassy_time::Duration, b: embassy_time::Duration) -> embassy_time::Duration {
a.checked_add(b).unwrap_or(embassy_time::Duration::MAX)
} Try / catch
// Rust panics are not catchable in embedded; use checked API instead:
let total = match a.checked_add(b) {
Some(t) => t,
None => Duration::MAX, // or return Err
}; Prevention
- Use checked_add instead of `+` for untrusted duration inputs
- Clamp timeouts to sane maxima before arithmetic
- Beware unit conversions that inflate tick counts
When it happens
Trigger: `a + b` where the combined tick count exceeds `Duration`'s maximum (e.g. adding two near-max durations, or accumulating durations in a loop without saturation).
Common situations: Computing deadlines from very large timeouts; summing user-provided durations; arithmetic on `Duration::MAX`; integer unit confusion (seconds vs micros) inflating values.
Related errors
- overflow when multiplying duration by scalar
- overflow when subtracting durations
- divide by zero error when dividing duration by scalar
- psc division overflow
- Passphrase is too short or too long
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/2cbbda9028282b8b.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-time/src/duration.rs:216
self.ticks.checked_mul(rhs as _).map(|ticks| Duration { ticks })
}
/// Divides one `Duration` by a scalar `u32`, returning a new `Duration` or `None` in the event of an overflow.
pub fn checked_div(self, rhs: u32) -> Option<Duration> {
self.ticks.checked_div(rhs as _).map(|ticks| Duration { ticks })
}
}
impl Add for Duration {
type Output = Duration;
/// Computes `Duration + Duration`. [Read more](Add)
///
/// ## Panics
///
/// Panics if the computed duration overflows.
fn add(self, rhs: Duration) -> Duration {
self.checked_add(rhs).expect("overflow when adding durations")
}
}
impl AddAssign for Duration {
/// Computes `Duration += Duration`. [Read more](AddAssign)
///
/// ## Panics
///
/// Panics if the computed duration overflows.
fn add_assign(&mut self, rhs: Duration) {
*self = *self + rhs;
}
}
impl Sub for Duration {
type Output = Duration;
/// Computes `Duration - Duration`. [Read more](Sub)View on GitHub (pinned to 463a07b963)