{"record":{"id":"4eb5624e696b4b31","repo":"Unity-Technologies/UnityCsReference","slug":"binding-type-should-derive-from-unity-type","errorCode":null,"errorMessage":"Binding type should derive from Unity type.","messagePattern":"Binding type should derive from Unity type\\.","errorType":"exception","errorClass":"InvalidCastException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/Animation/GameObjectRecorder.bindings.cs","lineNumber":73,"sourceCode":"            if (recursive)\n                components = target.GetComponentsInChildren(componentType, true);\n            else\n                components = target.GetComponents(componentType);\n\n            for (int i = 0; i < components.Length; ++i)\n                BindComponent(components[i]);\n        }\n\n        extern private static void Internal_Create([Writable] GameObjectRecorder self, [NotNull] GameObject root);\n\n        // Root.\n        extern public GameObject root { get; }\n\n        // Bindings.\n        public void Bind(EditorCurveBinding binding)\n        {\n            if (!binding.type.IsSubclassOf(typeof(UnityEngine.Object)))\n                throw new InvalidCastException(\"Binding type should derive from Unity type.\");\n\n            BindInternal(binding);\n        }\n\n        [NativeMethod(\"Bind\")]\n        extern private void BindInternal(EditorCurveBinding binding);\n\n        extern public void BindAll(GameObject target, bool recursive);\n        extern public void BindComponent([NotNull] Component component);\n\n        extern public EditorCurveBinding[] GetBindings();\n\n        // Recording.\n        extern public void TakeSnapshot(float dt);\n        extern public float currentTime { get; }\n        extern public bool isRecording { get; }\n\n        public void SaveToClip(AnimationClip clip)","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/Animation/GameObjectRecorder.bindings.cs#L55-L91","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure binding.type is a concrete UnityEngine.Object subclass (e.g. Transform, MonoBehaviour, SkinnedMeshRenderer).","Validate 'typeof(UnityEngine.Object).IsAssignableFrom(binding.type)' before calling Bind.","When binding an interface-implementing component, set type to the component type, not the interface.","Filter candidate types to those derived from UnityEngine.Object during binding construction."],"exampleFix":"// before\nrecorder.Bind(new EditorCurveBinding { type = typeof(IMyInterface), path = \"obj\", propertyName = \"m_Value\" });\n\n// after\nvar binding = new EditorCurveBinding { type = typeof(MyComponent), path = \"obj\", propertyName = \"m_Value\" };\nif (!typeof(UnityEngine.Object).IsAssignableFrom(binding.type))\n    throw new ArgumentException($\"{binding.type} is not a UnityEngine.Object subclass\");\nrecorder.Bind(binding);","handlingStrategy":"type-guard","validationCode":"if (!typeof(UnityEngine.Object).IsAssignableFrom(binding.type)) throw new ArgumentException($\"{binding.type} is not a UnityEngine.Object subclass\");","typeGuard":"static bool IsUnityBindingType(EditorCurveBinding b) => b.type != null && typeof(UnityEngine.Object).IsAssignableFrom(b.type);","tryCatchPattern":null,"preventionTips":["Set binding.type to a concrete Component/MonoBehaviour, never an interface.","Filter candidate types to UnityEngine.Object subclasses when building bindings generically.","Validate before Bind, especially for deserialized binding data."],"tags":["animation","invalid-cast","gameobject-recorder","editor","csharp"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}