Unity-Technologies/UnityCsReference · error · ArgumentNullException
bindings must be non-null
Error message
bindings must be non-null
What it means
Thrown by AnimationUtility.SetObjectReferenceCurves when the bindings array is null. The method zips bindings with keyframes element-wise; a null bindings array has no Length to compare against keyframes.Length and no elements to loop. The guard uses nameof for a precise paramName and runs before any native call.
Source
Thrown at Editor/Mono/Animation/AnimationUtility.bindings.cs:245
extern private static Type Internal_PropertyModificationToEditorCurveBinding(PropertyModification modification, [NotNull] GameObject gameObject, out EditorCurveBinding binding);
extern internal static PropertyModification EditorCurveBindingToPropertyModification(EditorCurveBinding binding, [NotNull] GameObject gameObject);
extern public static EditorCurveBinding[] GetCurveBindings([NotNull] AnimationClip clip);
extern public static EditorCurveBinding[] GetObjectReferenceCurveBindings([NotNull] AnimationClip clip);
extern public static ObjectReferenceKeyframe[] GetObjectReferenceCurve([NotNull] AnimationClip clip, EditorCurveBinding binding);
public static void SetObjectReferenceCurve(AnimationClip clip, EditorCurveBinding binding, ObjectReferenceKeyframe[] keyframes)
{
Internal_SetObjectReferenceCurve(clip, binding, keyframes, true);
Internal_InvokeOnCurveWasModified(clip, binding, keyframes != null ? CurveModifiedType.CurveModified : CurveModifiedType.CurveDeleted);
}
public static void SetObjectReferenceCurves(AnimationClip clip, EditorCurveBinding[] bindings, ObjectReferenceKeyframe[][] keyframes)
{
if (bindings == null)
throw new ArgumentNullException(nameof(bindings), $"{nameof(bindings)} must be non-null");
if (keyframes == null)
throw new ArgumentNullException(nameof(keyframes), $"{nameof(keyframes)} must be non-null");
if (bindings.Length != keyframes.Length)
throw new InvalidOperationException($"{nameof(bindings)} and {nameof(keyframes)} must be of equal length");
int length = bindings.Length;
for (int i = 0; i < length; i++)
{
SetObjectReferenceCurveNoSync(clip, bindings[i], keyframes[i]);
}
SyncEditorCurves(clip);
Internal_InvokeOnCurveWasModified(clip, new EditorCurveBinding(), CurveModifiedType.ClipModified);
}
internal static void SetObjectReferenceCurveNoSync(AnimationClip clip, EditorCurveBinding binding, ObjectReferenceKeyframe[] keyframes)
{
Internal_SetObjectReferenceCurve(clip, binding, keyframes, false);
Internal_InvokeOnCurveWasModified(clip, binding, keyframes != null ? CurveModifiedType.CurveModified : CurveModifiedType.CurveDeleted);View on GitHub (pinned to 225b0fbdb5)
Solutions
- Construct bindings with an explicit empty array fallback: bindings ?? Array.Empty<EditorCurveBinding>().
- Ensure bindings and keyframes are built in the same method with the same count.
- Validate both arrays (null + length) in a shared helper before all Set*Curves calls.
- If bindings are optional, early-return instead of calling with null.
Example fix
// before AnimationUtility.SetObjectReferenceCurves(clip, bindings, keyframes); // after bindings ??= Array.Empty<EditorCurveBinding>(); keyframes ??= Array.Empty<ObjectReferenceKeyframe[]>(); if (bindings.Length == 0) return; AnimationUtility.SetObjectReferenceCurves(clip, bindings, keyframes);
Defensive patterns
Strategy: validation
Validate before calling
if (bindings == null || bindings.Length == 0) return;
Type guard
static bool HasBindings(EditorCurveBinding[] b) => b != null && b.Length > 0;
Prevention
- Normalize collector output to Array.Empty<EditorCurveBinding>() instead of null.
- Build bindings and keyframes in the same pass to keep them paired.
- Centralize pre-validation for all Set*Curves calls.
When it happens
Trigger: Calling SetObjectReferenceCurves(clip, null, keyframes). Building the EditorCurveBinding[] from a LINQ query that returned null (rare, but possible from a custom collector returning null instead of empty). Reusing a stale field that was never initialized.
Common situations: Animation clip importers/post-processors that assemble object reference curves programmatically. Timeline tooling that deserializes binding lists from JSON where bindings was absent. Editor extensions syncing curves across clips.
Related errors
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/35455dbc219345fa.
Report an issue: GitHub.