bevyengine/bevy · error · CubicNurbsError

Wrong number of knots: expected {expected}, provided {provid

Error message

Wrong number of knots: expected {expected}, provided {provided}

What it means

CubicNurbs::new requires exactly control_points.len() + 4 knots (cubic degree plus one); any other count returns KnotsNumberMismatch with the expected and provided numbers (cubic_splines/mod.rs:655-663).

Source

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

        // since it means the first segment doesn't go "between" the first two control points, but
        // between the second and third instead.

        if segments.is_empty() {
            Err(InsufficientDataError {
                expected: 2,
                given: self.control_points.len(),
            })
        } else {
            Ok(CubicCurve { segments })
        }
    }
}

/// 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,

View on GitHub (pinned to 396ca72708)

Solutions

  1. Size the knot vector to control_points.len() + 4 before calling CubicNurbs::new.
  2. Pass None for knots to have open uniform knots generated automatically.
  3. Regenerate knots whenever the control point list changes length.

Example fix

// before
let nurbs = CubicNurbs::new(pts, None, Some(knots))?; // knots.len() != pts.len() + 4

// after
assert_eq!(knots.len(), pts.len() + 4);
let nurbs = CubicNurbs::new(pts, None, Some(knots))?;
// or let Bevy generate valid knots:
let nurbs = CubicNurbs::new(pts, None, None)?;
Defensive patterns

Strategy: validation

Validate before calling

use bevy_math::CubicNurbs;

fn knots_valid_len(n_points: usize, knots: &[f32]) -> bool {
    knots.len() == n_points + 4
}

// pass None instead of hand-building knots when in doubt:
let nurbs = CubicNurbs::new(points, None, None)?;

Try / catch

match CubicNurbs::new(points, weights, Some(knots)) {
    Err(CubicNurbsError::KnotsNumberMismatch { expected, provided }) => {
        // resize/regenerate the knot vector to expected
    }
    Ok(n) => { /* use n */ }
    Err(e) => warn!("{e}"),
}

Prevention

When it happens

Trigger: Passing a hand-built or imported knot vector whose length does not equal n + 4 where n is the control point count — e.g. after changing the point list without regenerating knots.

Common situations: Converting NURBS data from tools that use different degree conventions; hand-authoring knot arrays; editing control points without updating the knot vector.

Related errors


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