embassy-rs/embassy · error

divide by zero error when dividing duration by scalar

Error message

divide by zero error when dividing duration by scalar

What it means

`Duration / u32` in embassy-time is implemented via `checked_div`, which returns `None` only when the divisor is zero; `.expect("divide by zero error when dividing duration by scalar")` then panics. The message is misleading if you suspect overflow — division overflow is not the trigger, only `rhs == 0` (mirroring std's documented panic-on-divide-by-zero).

Solutions

  1. Check the divisor before dividing: `if n == 0 { ... } else { duration / n }`
  2. Clamp to at least 1: `duration / n.max(1)`
  3. Return a sensible default when the divisor is zero: `duration.checked_div(n).unwrap_or(Duration::ZERO)`

Example fix

// before
let per_item = total_timeout / item_count; // panics if item_count == 0
// after
let per_item = total_timeout / item_count.max(1);
Defensive patterns

Strategy: validation

Validate before calling

fn safe_div(d: embassy_time::Duration, n: u32) -> embassy_time::Duration {
    d.checked_div(n).unwrap_or(embassy_time::Duration::ZERO)
}

Try / catch

// Panic is not catchable in embedded; guard the divisor:
if n == 0 { return Duration::ZERO; }
let per = d / n;

Prevention

When it happens

Trigger: `duration / n` where `n` is a `u32` that is 0 — e.g. a computed divisor from an empty collection's `len()`, or an uninitialized/config-missing variable used as the divisor.

Common situations: Splitting a timeout across N items where N comes from an empty list; averaging over a count that can be zero; unit conversion where the divisor is read from config that defaulted to 0.

Related errors


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/06c2e8a80c19c421. Report an issue: GitHub.

Appendix: source

Thrown at embassy-time/src/duration.rs:303

    /// ## Panics
    ///
    /// Panics if the computed duration overflows.
    fn mul_assign(&mut self, rhs: u32) {
        *self = *self * rhs;
    }
}

impl Div<u32> for Duration {
    type Output = Duration;

    /// Computes `Duration / u32`. [Read more](Div)
    ///
    /// ## Panics
    ///
    /// Panics if dividing by zero.
    fn div(self, rhs: u32) -> Duration {
        self.checked_div(rhs)
            .expect("divide by zero error when dividing duration by scalar")
    }
}

impl DivAssign<u32> for Duration {
    /// Computes `Duration /= u32`. [Read more](DivAssign)
    ///
    /// ## Panics
    ///
    /// Panics if dividing by zero.
    fn div_assign(&mut self, rhs: u32) {
        *self = *self / rhs;
    }
}

impl<'a> fmt::Display for Duration {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} ticks", self.ticks)
    }

View on GitHub (pinned to 463a07b963)