{"record":{"id":"1126dc18e7277f33","repo":"stride3d/stride","slug":"can-not-construct-gizmo-of-type-gizmotype-it-does-not-have-a","errorCode":null,"errorMessage":"Can not construct gizmo of type {gizmoType}, it does not have a constructor taking a single EntityComponent","messagePattern":"Can not construct gizmo of type (.+?), it does not have a constructor taking a single EntityComponent","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"sources/editor/Stride.Assets.Presentation/AssetEditors/Gizmos/DispatcherGizmo.cs","lineNumber":95,"sourceCode":"            if (currentGizmoType != gizmoType)\n            {\n                // Delete the old gizmo\n                if (currentGizmo != null)\n                {\n                    currentGizmo.Dispose();\n                    currentGizmo = null;\n                }\n\n                // Create the new gizmo\n                if (gizmoType != null && typeof(IGizmo).IsAssignableFrom(gizmoType))\n                {\n                    if (gizmoType.GetConstructor(new[] { typeof(EntityComponent) }) != null)\n                    {\n                        currentGizmo = (EntityGizmo<TComponent>)Activator.CreateInstance(gizmoType, Component);\n                    }\n                    else\n                    {\n                        throw new Exception($\"Can not construct gizmo of type {gizmoType}, it does not have a constructor taking a single {nameof(EntityComponent)}\");\n                    }\n                }\n\n                // Initialize the new gizmo\n                currentGizmo?.Initialize(Services, EditorScene);\n\n                // Set the selected and enabled state of the gizmo\n                IsSelected = IsSelected;\n                IsEnabled = IsEnabled;\n            }\n            currentGizmoType = gizmoType;\n\n            // update the current gizmo\n            currentGizmo?.Update();\n        }\n\n        protected override void Destroy()\n        {","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/editor/Stride.Assets.Presentation/AssetEditors/Gizmos/DispatcherGizmo.cs#L77-L113","documentation":"DispatcherGizmo.Update instantiates a gizmo object via Activator.CreateInstance when the edited component type changes. Gizmo types must expose a constructor taking exactly one EntityComponent parameter; if the registered gizmo type's constructor does not match, reflection-based construction is impossible and a plain Exception is thrown.","triggerScenarios":"Registering or attributing a custom EntityGizmo<TComponent> whose constructor signature differs (e.g. parameterless ctor, extra parameters, or ctor taking a derived component type not matching typeof(EntityComponent) exactly for the reflection probe).","commonSituations":"Writing a custom gizmo for a custom entity component and forgetting the (EntityComponent) constructor; copy-pasting a gizmo class and changing its constructor; signature drift after refactoring base classes.","solutions":["Add a constructor to the gizmo type accepting a single EntityComponent (or the exact component type registered) and delegate to the base constructor.","Check the gizmo type's registration/attribute points at the intended gizmo class, not an abstract helper type.","Unit-test gizmo construction with Activator.CreateInstance in a plugin's startup to fail early."],"exampleFix":"// before\npublic class MyGizmo : EntityGizmo<MyComponent>\n{\n    public MyGizmo() { } // no EntityComponent ctor\n}\n// after\npublic class MyGizmo : EntityGizmo<MyComponent>\n{\n    public MyGizmo(EntityComponent component) : base(component) { }\n}","handlingStrategy":"validation","validationCode":"if (gizmoType.GetConstructor(new[] { typeof(EntityComponent) }) == null)\n    throw new InvalidOperationException($\"{gizmoType} must have a single EntityComponent constructor.\");","typeGuard":"bool IsValidGizmoType(Type t) => !t.IsAbstract && t.GetConstructor(new[] { typeof(EntityComponent) }) != null;","tryCatchPattern":"try { currentGizmo = (EntityGizmo<TComponent>)Activator.CreateInstance(gizmoType, Component); }\ncatch (Exception ex) { log.Error($\"Bad gizmo type {gizmoType}: {ex.Message}\"); }","preventionTips":["Always give custom gizmos a public ctor taking EntityComponent","Scan registered gizmo types at plugin startup with reflection","Keep gizmo constructors aligned with the base EntityGizmo pattern"],"tags":["reflection","constructor","gizmo","activator"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}