Unity-Technologies/UnityCsReference · error · InvalidCastException

Binding type should derive from Unity type.

Error message

Binding type should derive from Unity type.

What it means

Thrown by GameObjectRecorder.Bind(EditorCurveBinding) when binding.type is not a subclass of UnityEngine.Object. The recorder binds native properties on Unity objects, so a binding whose type is a plain C# class or interface cannot be resolved; BindInternal would fail in native, so the managed guard throws InvalidCastException first.

Source

Thrown at Editor/Mono/Animation/GameObjectRecorder.bindings.cs:73

            if (recursive)
                components = target.GetComponentsInChildren(componentType, true);
            else
                components = target.GetComponents(componentType);

            for (int i = 0; i < components.Length; ++i)
                BindComponent(components[i]);
        }

        extern private static void Internal_Create([Writable] GameObjectRecorder self, [NotNull] GameObject root);

        // Root.
        extern public GameObject root { get; }

        // Bindings.
        public void Bind(EditorCurveBinding binding)
        {
            if (!binding.type.IsSubclassOf(typeof(UnityEngine.Object)))
                throw new InvalidCastException("Binding type should derive from Unity type.");

            BindInternal(binding);
        }

        [NativeMethod("Bind")]
        extern private void BindInternal(EditorCurveBinding binding);

        extern public void BindAll(GameObject target, bool recursive);
        extern public void BindComponent([NotNull] Component component);

        extern public EditorCurveBinding[] GetBindings();

        // Recording.
        extern public void TakeSnapshot(float dt);
        extern public float currentTime { get; }
        extern public bool isRecording { get; }

        public void SaveToClip(AnimationClip clip)

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Ensure binding.type is a concrete UnityEngine.Object subclass (e.g. Transform, MonoBehaviour, SkinnedMeshRenderer).
  2. Validate 'typeof(UnityEngine.Object).IsAssignableFrom(binding.type)' before calling Bind.
  3. When binding an interface-implementing component, set type to the component type, not the interface.
  4. Filter candidate types to those derived from UnityEngine.Object during binding construction.

Example fix

// before
recorder.Bind(new EditorCurveBinding { type = typeof(IMyInterface), path = "obj", propertyName = "m_Value" });

// after
var binding = new EditorCurveBinding { type = typeof(MyComponent), path = "obj", propertyName = "m_Value" };
if (!typeof(UnityEngine.Object).IsAssignableFrom(binding.type))
    throw new ArgumentException($"{binding.type} is not a UnityEngine.Object subclass");
recorder.Bind(binding);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!typeof(UnityEngine.Object).IsAssignableFrom(binding.type)) throw new ArgumentException($"{binding.type} is not a UnityEngine.Object subclass");

Type guard

static bool IsUnityBindingType(EditorCurveBinding b) => b.type != null && typeof(UnityEngine.Object).IsAssignableFrom(b.type);

Prevention

When it happens

Trigger: Passing an EditorCurveBinding whose type field was set to a custom POCO or an interface. Reusing a binding built for a MonoBehaviour field path where type ended up as the C# interface type rather than the concrete component. Constructing EditorCurveBinding via reflection with a non-Unity type.

Common situations: Custom recorder tooling that builds bindings generically. Bindings assembled from serialized data where the type string resolved to a non-Unity type. Porting Animator bindings to GameObjectRecorder.

Related errors


AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13). Data as JSON: /api/errors/4eb5624e696b4b31. Report an issue: GitHub.