{"record":{"id":"0abe4773b7471a2a","repo":"stride3d/stride","slug":"value-cannot-be-null-parameter-classtype","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'classType')","messagePattern":"Value cannot be null\\. \\(Parameter 'classType'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.UI/Events/EventManager.cs","lineNumber":77,"sourceCode":"                types.Add(currentType);\n                currentType = currentType.GetTypeInfo().BaseType;\n            }\n\n            return types.Where(t => OwnerToEvents.ContainsKey(t)).SelectMany(t => OwnerToEvents[t].Values).ToArray();\n        }\n\n        /// <summary>\n        /// Registers a class handler for a particular routed event, with the option to handle events where event data is already marked handled.\n        /// </summary>\n        /// <param name=\"classType\">The type of the class that is declaring class handling.</param>\n        /// <param name=\"routedEvent\">The routed event identifier of the event to handle.</param>\n        /// <param name=\"handler\">A reference to the class handler implementation.</param>\n        /// <param name=\"handledEventsToo\">true to invoke this class handler even if arguments of the routed event have been marked as handled; \n        /// false to retain the default behavior of not invoking the handler on any marked-handled event.</param>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"classType\"/>, <paramref name=\"routedEvent\"/>, or <paramref name=\"handler\"/> is null.</exception>\n        public static void RegisterClassHandler<T>(Type classType, RoutedEvent<T> routedEvent, EventHandler<T> handler, bool handledEventsToo = false) where T : RoutedEventArgs\n        {\n            if (classType == null) throw new ArgumentNullException(nameof(classType));\n            if (routedEvent == null) throw new ArgumentNullException(nameof(routedEvent));\n            if (handler == null) throw new ArgumentNullException(nameof(handler));\n\n            lock(SyncRoot)\n            {\n                if (!ClassesToClassHandlers.ContainsKey(classType))\n                    ClassesToClassHandlers[classType] = new Dictionary<RoutedEvent, RoutedEventHandlerInfo>();\n\n                ClassesToClassHandlers[classType][routedEvent] = new RoutedEventHandlerInfo<T>(handler, handledEventsToo); \n            }\n        }\n\n        /// <summary>\n        /// Get the class handler for the class <paramref name=\"classType\"/> and routed event <paramref name=\"routedEvent\"/>.\n        /// </summary>\n        /// <param name=\"classType\">The type of the class that is handling the event.</param>\n        /// <param name=\"routedEvent\">The routed event to handle</param>\n        /// <returns>The class handler</returns>","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.UI/Events/EventManager.cs#L59-L95","documentation":"EventManager.RegisterClassHandler attaches a handler for a routed event to all instances of a class, so the target class type is mandatory. A null classType is rejected immediately with ArgumentNullException(nameof(classType)); routedEvent and handler are checked in the same block.","triggerScenarios":"Calling RegisterClassHandler<T>(null, routedEvent, handler) with an unresolved class type, e.g. typeof expression replaced by a reflection lookup that failed or a config-driven type name that could not be loaded.","commonSituations":"Bootstrap/event-wiring code running before plugin types are loaded; renamed or removed control classes leaving stale registrations; generic registration helpers receiving a null type parameter.","solutions":["Pass the concrete class, e.g. RegisterClassHandler<Button>(typeof(Button), ...)","Resolve the type via reflection with error handling and null-check it before registering","Remove or fix stale registrations for classes that no longer exist"],"exampleFix":"// before\nEventManager.RegisterClassHandler<Button>(null, UIElement.MouseMoveEvent, OnMouseMove); // throws\n// after\nEventManager.RegisterClassHandler<Button>(typeof(Button), UIElement.MouseMoveEvent, OnMouseMove);","handlingStrategy":"validation","validationCode":"if (classType == null || routedEvent == null || handler == null)\n    throw new ArgumentException(\"classType, routedEvent and handler are required\");","typeGuard":"bool CanRegisterHandler(Type classType) => classType != null;","tryCatchPattern":"try\n{\n    EventManager.RegisterClassHandler<T>(classType, routedEvent, handler);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"classType\")\n{\n    // type could not be resolved; fix bootstrap order or type name\n}","preventionTips":["Use typeof(T) literals for class handlers","Null-check reflection-resolved types before registration","Register handlers after all plugin types are loaded"],"tags":["routed-events","null-argument","eventmanager"],"backgroundTag":"null-argument","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}