bevyengine/bevy · error · SpacedPointsError

Cannot extract spaced points from an unbounded interval

Error message

Cannot extract spaced points from an unbounded interval

What it means

SpacedPointsError is returned by Interval::spaced_points when the interval is unbounded — start = -INF or end = +INF (e.g. Interval::EVERYTHING). Spaced points are evenly distributed positions across the interval at a fixed spacing or count; that is undefined over an infinite span, so the method refuses.

Source

Thrown at crates/bevy_math/src/curve/interval.rs:42

    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")]
    TargetUnbounded,
}

impl Interval {
    /// Create a new [`Interval`] with the specified `start` and `end`. The interval can be unbounded

View on GitHub (pinned to 396ca72708)

Solutions

  1. Construct a bounded interval first (Interval::new(start, end) with finite values) and call spaced_points on that.
  2. Check `interval.is_bounded()` before calling and skip or clamp when false.
  3. If the interval came from a curve, take a finite slice of the domain (e.g. intersect with a window) before sampling points.

Example fix

// before
let points: Vec<f32> = Interval::EVERYTHING.spaced_points(0.5).collect(); // SpacedPointsError

// after
let window = Interval::new(0.0, 10.0)?; // the range you actually care about
let points: Vec<f32> = window.spaced_points(0.5).collect();
Defensive patterns

Strategy: validation

Validate before calling

if interval.is_bounded() {
    let points: Vec<f32> = interval.spaced_points(0.5).collect();
} else {
    // clamp to a finite window first, e.g. Interval::new(0.0, 10.0)?
}

Try / catch

let points = match interval.spaced_points(spacing) {
    Ok(iter) => iter.collect::<Vec<_>>(),
    Err(SpacedPointsError) => {
        let window = interval.intersect(Interval::new(0.0, horizon))?; // finite slice
        window.spaced_points(spacing)?.collect()
    }
};

Prevention

When it happens

Trigger: interval.spaced_points(spacing) or spaced_points_inclusive on Interval::EVERYTHING or any interval built with infinite endpoints; domains flowing from unclamped time accumulators (delta time summed without a cap) into a curve's domain before calling spaced_points.

Common situations: Using EVERYTHING as a convenience 'all times' domain then trying to enumerate ticks; generating checkpoints along an unbounded game-time axis; forgetting to clamp a physics-time accumulator that becomes INF.

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/8924bba2697b9774. Report an issue: GitHub.