bevyengine/bevy · error · InvalidIntervalError
The resulting interval would be invalid (empty or with a NaN
Error message
The resulting interval would be invalid (empty or with a NaN endpoint)
What it means
InvalidIntervalError is returned whenever an operation would produce an empty or NaN-endpoint Interval. Interval::new(start, end) rejects start > end and any NaN argument; Interval::intersect rejects producing an empty result (disjoint intervals); the interval()/TryFrom<RangeInclusive> helpers and curve adaptors like zip (intersecting two curve domains) can surface it too. Intervals must satisfy start <= end with both endpoints finite/valid.
Source
Thrown at crates/bevy_math/src/curve/interval.rs:37
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Debug, PartialEq, Clone)
)]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct Interval {
start: f32,
end: f32,
}
/// An error that indicates that an operation would have returned an invalid [`Interval`].
#[derive(Debug, Error)]
#[error("The resulting interval would be invalid (empty or with a NaN endpoint)")]
pub struct InvalidIntervalError;
/// An error indicating that spaced points could not be extracted from an unbounded interval.
#[derive(Debug, Error)]
#[error("Cannot extract spaced points from an unbounded interval")]
pub struct SpacedPointsError;
/// An error indicating that a linear map between intervals could not be constructed because of
/// unboundedness.
#[derive(Debug, Error)]
#[error("Could not construct linear function to map between intervals")]
pub(super) enum LinearMapError {
/// The source interval being mapped out of was unbounded.
#[error("The source interval is unbounded")]
SourceUnbounded,
/// The target interval being mapped into was unbounded.
#[error("The target interval is unbounded")]View on GitHub (pinned to 396ca72708)
Solutions
- Order endpoints before constructing: Interval::new(a.min(b), a.max(b)).
- Guard against NaN: check a.is_finite() && b.is_finite() before calling.
- For zip/intersect of possibly-disjoint ranges, check overlap first (max(starts) <= min(ends)) and handle the disjoint case explicitly instead of unwrapping.
Example fix
// before
let domain = Interval::new(t_max, t_min)?; // swapped -> InvalidIntervalError
let zipped = curve_a.zip(curve_b)?; // disjoint domains -> InvalidIntervalError
// after
let domain = Interval::new(t_min.min(t_max), t_min.max(t_max))?;
let zipped = if curve_a.domain().intersect(curve_b.domain()).is_ok() {
Some(curve_a.zip(curve_b)?)
} else {
None // no overlap: skip or report
}; Defensive patterns
Strategy: validation
Validate before calling
fn valid_interval(a: f32, b: f32) -> bool {
a.is_finite() && b.is_finite() && a <= b
}
if valid_interval(start, end) {
let interval = Interval::new(start, end)?;
} Try / catch
let interval = match Interval::new(start, end) {
Ok(iv) => iv,
Err(InvalidIntervalError) => Interval::new(end, start)?, // swapped inputs: normalize order
}; Prevention
- Always order endpoints: Interval::new(a.min(b), a.max(b)).
- Reject NaN early wherever times/positions are computed (0.0/0.0, unclamped trig).
- Before zip/intersect, check overlap: max(a.start, b.start) <= min(a.end, b.end), and handle the disjoint case explicitly instead of unwrapping the Result.
When it happens
Trigger: Interval::new(end, start) with swapped arguments; interval(a, b) where a > b; passing NaN (e.g. from 0.0/0.0); curve1.zip(curve2) on curves with disjoint domains; intersect(Interval::new(0.,1.)?, Interval::new(2.,3.)?) yielding empty.
Common situations: Computing domain endpoints from data where min/max were never ordered (single-element iterates, reversed loops); NaN leaking from trig or normalization math; zipping two animations whose time ranges don't overlap.
Related errors
- Cannot create an EvenCore over an unbounded domain
- Need at least two unique samples to create an UnevenCore, bu
- Need at least two unique samples to create a ChunkedUnevenCo
- Cannot extract spaced points from an unbounded interval
- Not enough data to build curve: needed at least {expected} c
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/9a05ccc79c46c19c.
Report an issue: GitHub.