{"record":{"id":"e28e54e3393fae80","repo":"Unity-Technologies/UnityCsReference","slug":"bindings-and-keyframes-must-be-of-equal-length","errorCode":null,"errorMessage":"bindings and keyframes must be of equal length","messagePattern":"bindings and keyframes must be of equal length","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/Animation/AnimationUtility.bindings.cs","lineNumber":249,"sourceCode":"        extern public static EditorCurveBinding[] GetCurveBindings([NotNull] AnimationClip clip);\n        extern public static EditorCurveBinding[] GetObjectReferenceCurveBindings([NotNull] AnimationClip clip);\n\n        extern public static ObjectReferenceKeyframe[] GetObjectReferenceCurve([NotNull] AnimationClip clip, EditorCurveBinding binding);\n\n        public static void SetObjectReferenceCurve(AnimationClip clip, EditorCurveBinding binding, ObjectReferenceKeyframe[] keyframes)\n        {\n            Internal_SetObjectReferenceCurve(clip, binding, keyframes, true);\n            Internal_InvokeOnCurveWasModified(clip, binding, keyframes != null ? CurveModifiedType.CurveModified : CurveModifiedType.CurveDeleted);\n        }\n\n        public static void SetObjectReferenceCurves(AnimationClip clip, EditorCurveBinding[] bindings, ObjectReferenceKeyframe[][] keyframes)\n        {\n            if (bindings == null)\n                throw new ArgumentNullException(nameof(bindings), $\"{nameof(bindings)} must be non-null\");\n            if (keyframes == null)\n                throw new ArgumentNullException(nameof(keyframes), $\"{nameof(keyframes)} must be non-null\");\n            if (bindings.Length != keyframes.Length)\n                throw new InvalidOperationException($\"{nameof(bindings)} and {nameof(keyframes)} must be of equal length\");\n\n            int length = bindings.Length;\n            for (int i = 0; i < length; i++)\n            {\n                SetObjectReferenceCurveNoSync(clip, bindings[i], keyframes[i]);\n            }\n            SyncEditorCurves(clip);\n            Internal_InvokeOnCurveWasModified(clip, new EditorCurveBinding(), CurveModifiedType.ClipModified);\n        }\n\n        internal static void SetObjectReferenceCurveNoSync(AnimationClip clip, EditorCurveBinding binding, ObjectReferenceKeyframe[] keyframes)\n        {\n            Internal_SetObjectReferenceCurve(clip, binding, keyframes, false);\n            Internal_InvokeOnCurveWasModified(clip, binding, keyframes != null ? CurveModifiedType.CurveModified : CurveModifiedType.CurveDeleted);\n        }\n\n        [NativeMethod(ThrowsException = true)]\n        extern private static void Internal_SetObjectReferenceCurve([NotNull] AnimationClip clip, EditorCurveBinding binding, ObjectReferenceKeyframe[] keyframes, bool updateMuscleClip);","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/Animation/AnimationUtility.bindings.cs#L231-L267","documentation":"Thrown by AnimationUtility.SetObjectReferenceCurves when bindings.Length != keyframes.Length. The batch API zips the two arrays element-wise; a length mismatch would either leave bindings un-synced or index out of range, so it throws InvalidOperationException before the loop and the final SyncEditorCurves.","triggerScenarios":"Bindings built from one set of properties and keyframes from another. A jagged keyframes array built by pushing one entry per clip but bindings built per-property. Removing an element from one array and forgetting the other.","commonSituations":"Migrating clips between rigs where property bindings change count. Timeline/Animator tooling that filters keyframes after building bindings. Code that appends to one list in a loop but not the other.","solutions":["Assert Debug.Assert(bindings.Length == keyframes.Length, context) at construction.","Build bindings and keyframes together in one pass so they cannot diverge.","Add a length-check helper and call it before every Set*Curves invocation.","If lengths legitimately differ, zip to the shorter length explicitly and document why."],"exampleFix":"// before\nAnimationUtility.SetObjectReferenceCurves(clip, bindings, keyframes); // mismatched lengths\n\n// after\nif (bindings.Length != keyframes.Length)\n    throw new InvalidOperationException($\"bindings({bindings.Length}) != keyframes({keyframes.Length}) for {clip.name}\");\nAnimationUtility.SetObjectReferenceCurves(clip, bindings, keyframes);","handlingStrategy":"validation","validationCode":"if (bindings.Length != keyframes.Length) throw new InvalidOperationException($\"bindings({bindings.Length}) != keyframes({keyframes.Length})\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build both arrays in one loop so lengths cannot diverge.","Assert length equality at construction with a context message.","Filter both arrays together, never independently."],"tags":["animation","invalid-operation","editor","array-length","csharp"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}