{"record":{"id":"275cb408ded9980b","repo":"Unity-Technologies/UnityCsReference","slug":"curves-must-be-non-null","errorCode":null,"errorMessage":"curves must be non-null","messagePattern":"curves must be non-null","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/Animation/AnimationUtility.bindings.cs","lineNumber":282,"sourceCode":"        }\n\n        [NativeMethod(ThrowsException = true)]\n        extern private static void Internal_SetObjectReferenceCurve([NotNull] AnimationClip clip, EditorCurveBinding binding, ObjectReferenceKeyframe[] keyframes, bool updateMuscleClip);\n\n        extern public static AnimationCurve GetEditorCurve([NotNull] AnimationClip clip, EditorCurveBinding binding);\n\n        public static void SetEditorCurve(AnimationClip clip, EditorCurveBinding binding, AnimationCurve curve)\n        {\n            Internal_SetEditorCurve(clip, binding, curve, true);\n            Internal_InvokeOnCurveWasModified(clip, binding, curve != null ? CurveModifiedType.CurveModified : CurveModifiedType.CurveDeleted);\n        }\n\n        public static void SetEditorCurves(AnimationClip clip, EditorCurveBinding[] bindings, AnimationCurve[] curves)\n        {\n            if (bindings == null)\n                throw new ArgumentNullException(nameof(bindings), $\"{nameof(bindings)} must be non-null\");\n            if (curves == null)\n                throw new ArgumentNullException(nameof(curves), $\"{nameof(curves)} must be non-null\");\n            if (bindings.Length != curves.Length)\n                throw new InvalidOperationException($\"{nameof(bindings)} and {nameof(curves)} must be of equal length\");\n\n            int length = bindings.Length;\n            for (int i = 0; i < length; i++)\n            {\n                SetEditorCurveNoSync(clip, bindings[i], curves[i]);\n            }\n            SyncEditorCurves(clip);\n\n            Internal_InvokeOnCurveWasModified(clip, new EditorCurveBinding(), AnimationUtility.CurveModifiedType.ClipModified);\n        }\n\n        internal static void SetEditorCurveNoSync(AnimationClip clip, EditorCurveBinding binding, AnimationCurve curve)\n        {\n            Internal_SetEditorCurve(clip, binding, curve, false);\n            Internal_InvokeOnCurveWasModified(clip, binding, curve != null ? CurveModifiedType.CurveModified : CurveModifiedType.CurveDeleted);\n        }","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/Animation/AnimationUtility.bindings.cs#L264-L300","documentation":"Thrown by AnimationUtility.SetEditorCurves when the curves array (AnimationCurve[]) is null. Singular SetEditorCurve accepts a null curve to delete that binding, but the batch form requires a non-null array so it can compare length with bindings and iterate. Guard order: bindings null, then curves null, then length mismatch.","triggerScenarios":"Calling SetEditorCurves(clip, bindings, null). A curve builder that returns null for 'no curves'. Reusing the singular API's null-means-delete semantics in the plural API.","commonSituations":"Programmatic clip generation defaulting curves to null. Serialization round-trips where an empty curves array came back as null. Copying from SetEditorCurve singular usage.","solutions":["Default to Array.Empty<AnimationCurve>() instead of null when no curves exist.","If you mean to delete curves, pass non-null array of nulls (one per binding) or use the singular API per binding.","Build curves and bindings in one pass.","Validate at the boundary before calling."],"exampleFix":"// before\nvar curves = hasData ? BuildCurves() : null;\nAnimationUtility.SetEditorCurves(clip, bindings, curves);\n\n// after\nvar curves = hasData ? BuildCurves() : Array.Empty<AnimationCurve>();\nAnimationUtility.SetEditorCurves(clip, bindings, curves);","handlingStrategy":"validation","validationCode":"if (curves == null) curves = Array.Empty<AnimationCurve>();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not reuse the singular SetEditorCurve null-means-delete semantics in the batch API.","Default curve arrays to empty, not null.","To delete via batch, pass a non-null array of nulls matching bindings length."],"tags":["animation","argument-null","editor","csharp"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}