Unity-Technologies/UnityCsReference · error · ArgumentNullException
keyframes must be non-null
Error message
keyframes must be non-null
What it means
Thrown by AnimationUtility.SetObjectReferenceCurves when the keyframes array (the jagged ObjectReferenceKeyframe[][]) is null. It is checked right after bindings so that the subsequent length-comparison guard has a real Length on both sides. SetObjectReferenceCurve (singular) allows null keyframes to delete a curve, but the plural batch form requires non-null.
Source
Thrown at Editor/Mono/Animation/AnimationUtility.bindings.cs:247
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
- Default keyframes to an empty jagged array when there is nothing to write.
- Build keyframes to exactly mirror bindings length, element for element.
- Map a null result to Array.Empty<ObjectReferenceKeyframe[]>() at the boundary.
- If you intend to delete all curves, call SetObjectReferenceCurve per binding with null instead of the batch API.
Example fix
// before var keyframes = clipData.HasKeyframes ? BuildKeyframes() : null; AnimationUtility.SetObjectReferenceCurves(clip, bindings, keyframes); // after var keyframes = clipData.HasKeyframes ? BuildKeyframes() : Array.Empty<ObjectReferenceKeyframe[]>(); AnimationUtility.SetObjectReferenceCurves(clip, bindings, keyframes);
Defensive patterns
Strategy: validation
Validate before calling
if (keyframes == null) keyframes = Array.Empty<ObjectReferenceKeyframe[]>();
Prevention
- Remember the plural API forbids null keyframes even though the singular API allows null to delete.
- Default jagged keyframe arrays to empty rather than null.
- Round-trip serialization must distinguish empty vs absent.
When it happens
Trigger: Calling SetObjectReferenceCurves(clip, bindings, null). A collector that returns null for 'no keyframes' instead of an empty jagged array. Deserialized keyframe data where the outer array node was missing.
Common situations: Programmatic clip generation that conditionally produces keyframes and defaults to null. JSON/serialization round-trips where an empty keyframes list serialized as null on load. Copy-paste from the singular API where null is legal.
Related errors
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/92a24688438b329f.
Report an issue: GitHub.