bevyengine/bevy · error · CubicNurbsError

Invalid knots: all knots are equal

Error message

Invalid knots: all knots are equal

What it means

CubicNurbsError::ConstantKnots is returned by CubicNurbs::new when every knot in the provided knot vector equals its neighbor — i.e. all knots are the same value. NURBS evaluation needs at least one strictly increasing knot pair to define a nonzero parameter range; a constant vector gives zero curve length and division by zero downstream, so construction is rejected. Note the vector must still be non-descending (n + 4 entries for n control points), and at least one adjacent pair must strictly increase.

Source

Thrown at crates/bevy_math/src/cubic_splines/mod.rs:540

}

/// Error during construction of [`CubicNurbs`]
#[derive(Clone, Debug, Error)]
pub enum CubicNurbsError {
    /// Provided the wrong number of knots.
    #[error("Wrong number of knots: expected {expected}, provided {provided}")]
    KnotsNumberMismatch {
        /// Expected number of knots
        expected: usize,
        /// Provided number of knots
        provided: usize,
    },
    /// The provided knots had a descending knot pair. Subsequent knots must
    /// either increase or stay the same.
    #[error("Invalid knots: contains descending knot pair")]
    DescendingKnots,
    /// The provided knots were all equal. Knots must contain at least one increasing pair.
    #[error("Invalid knots: all knots are equal")]
    ConstantKnots,
    /// Provided a different number of weights and control points.
    #[error("Incorrect number of weights: expected {expected}, provided {provided}")]
    WeightsNumberMismatch {
        /// Expected number of weights
        expected: usize,
        /// Provided number of weights
        provided: usize,
    },
    /// The number of control points provided is less than 4.
    #[error("Not enough control points, at least 4 are required, {provided} were provided")]
    NotEnoughControlPoints {
        /// The number of control points provided
        provided: usize,
    },
}

/// Non-uniform Rational B-Splines (NURBS) are a powerful generalization of the [`CubicBSpline`] which can

View on GitHub (pinned to 396ca72708)

Solutions

  1. Pass `None` for knots to use the default open_uniform_knots, which is always valid.
  2. Fix the vector so it is non-descending and contains at least one strict increase, e.g. open uniform [0,0,0,0,1,1,1,1] for 4 control points.
  3. If knots come from a generator, debug why the delta is zero: print min/max before constructing.

Example fix

// before
let n = control_points.len();
let nurbs = CubicNurbs::new(control_points, None, Some(vec![0.5; n + 4]))?; // ConstantKnots

// after
let nurbs = CubicNurbs::new(control_points, None, None)?; // open uniform knots
// or explicitly:
let knots = CubicNurbs::open_uniform_knots(n).unwrap();
let nurbs = CubicNurbs::new(control_points, None, Some(knots))?;
Defensive patterns

Strategy: try-catch

Validate before calling

fn knots_valid(knots: &[f32]) -> bool {
    knots.windows(2).all(|w| w[0] <= w[1]) // non-descending
        && knots.windows(2).any(|w| w[0] < w[1]) // at least one strict increase
}

// then: if knots_valid(&knots) { CubicNurbs::new(points, None, Some(knots))? } else { ... }

Try / catch

match CubicNurbs::new(&points, None, Some(knots.clone())) {
    Ok(nurbs) => nurbs,
    Err(CubicNurbsError::ConstantKnots) => {
        // fall back to default open uniform knots
        CubicNurbs::new(&points, None, None)?
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling CubicNurbs::new(points, weights, Some(vec![0.0; n + 4])) with an all-identical knot vector; generating knots programmatically where the increment is computed as 0 (e.g. dividing by a zero span or a constant generator function).

Common situations: Authoring NURBS data by hand in an editor/exporter and copying one knot value across; procedural knot generation with a `step` that collapses to zero due to an integer division or a bad min/max normalization.

Related errors


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