{"record":{"id":"30ea8defe70c0818","repo":"bevyengine/bevy","slug":"not-enough-control-points-at-least-4-are-required","errorCode":null,"errorMessage":"Not enough control points, at least 4 are required, {provided} were provided","messagePattern":"Not enough control points, at least 4 are required, (.+?) were provided","errorType":"exception","errorClass":"CubicNurbsError","httpStatus":null,"severity":"error","filePath":"crates/bevy_math/src/cubic_splines/mod.rs","lineNumber":551,"sourceCode":"        provided: usize,\n    },\n    /// The provided knots had a descending knot pair. Subsequent knots must\n    /// either increase or stay the same.\n    #[error(\"Invalid knots: contains descending knot pair\")]\n    DescendingKnots,\n    /// The provided knots were all equal. Knots must contain at least one increasing pair.\n    #[error(\"Invalid knots: all knots are equal\")]\n    ConstantKnots,\n    /// Provided a different number of weights and control points.\n    #[error(\"Incorrect number of weights: expected {expected}, provided {provided}\")]\n    WeightsNumberMismatch {\n        /// Expected number of weights\n        expected: usize,\n        /// Provided number of weights\n        provided: usize,\n    },\n    /// The number of control points provided is less than 4.\n    #[error(\"Not enough control points, at least 4 are required, {provided} were provided\")]\n    NotEnoughControlPoints {\n        /// The number of control points provided\n        provided: usize,\n    },\n}\n\n/// Non-uniform Rational B-Splines (NURBS) are a powerful generalization of the [`CubicBSpline`] which can\n/// represent a much more diverse class of curves (like perfect circles and ellipses).\n///\n/// ### Non-uniformity\n///\n/// The 'NU' part of NURBS stands for \"Non-Uniform\". This has to do with a parameter called 'knots'.\n/// The knots are a non-decreasing sequence of floating point numbers. The first and last three pairs of\n/// knots control the behavior of the curve as it approaches its endpoints. The intermediate pairs\n/// each control the length of one segment of the curve. Multiple repeated knot values are called\n/// \"knot multiplicity\". Knot multiplicity in the intermediate knots causes a \"zero-length\" segment,\n/// and can create sharp corners.\n///","sourceCodeStart":533,"sourceCodeEnd":569,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_math/src/cubic_splines/mod.rs#L533-L569","documentation":"CubicNurbsError::NotEnoughControlPoints is returned by CubicNurbs::new when fewer than 4 control points are provided. A cubic (degree-3) B-spline segment needs 4 control points minimum; below that there is no cubic segment to solve for. `provided` reports how many points you actually passed.","triggerScenarios":"CubicNurbs::new(vec![p0, p1, p2], ...) with 3 or fewer points; dynamically built point lists that can be short at runtime (empty spawn lists, single sample from input).","commonSituations":"Prototyping with 2-3 clicked points in an editor; edge-case runtime data (a path with one waypoint); tests with minimal fixtures.","solutions":["Provide at least 4 control points, e.g. duplicate end points to pad.","For 2 points use LinearSpline, for interpolation through few points use Hermite or CubicBezier (point-interpolation) instead of NURBS.","Guard runtime-built lists: branch to a different curve type when points.len() < 4."],"exampleFix":"// before\nlet nurbs = CubicNurbs::new(vec![p0, p1, p2], None, None)?; // NotEnoughControlPoints\n\n// after\nlet curve = if points.len() >= 4 {\n    CubicNurbs::new(points.iter().copied(), None, None)?.to_curve()?.into()\n} else {\n    LinearSpline::new(points.iter().copied()).to_curve()?.into()\n};","handlingStrategy":"validation","validationCode":"if points.len() < 4 {\n    // pick a lower-degree fallback instead of calling CubicNurbs::new\n}","typeGuard":null,"tryCatchPattern":"let curve = match CubicNurbs::new(&points, None, None) {\n    Ok(nurbs) => nurbs.to_curve()?,\n    Err(CubicNurbsError::NotEnoughControlPoints { .. }) => {\n        LinearSpline::new(points.clone()).to_curve()? // graceful downgrade for short lists\n    }\n    Err(e) => return Err(e.into()),\n};","preventionTips":["Branch on points.len() before choosing the spline type: >= 4 -> NURBS/BSpline, 2-3 -> Linear/Hermite.","Pad short lists by duplicating endpoints when a NURBS specifically is required.","Unit-test curve builders with 0, 1, and 3 point inputs."],"tags":["rust","bevy","math","spline","nurbs","runtime"],"backgroundTag":"invalid-spline-parameters","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}