stride3d/stride · error · ArgumentNullException
Value cannot be null. (Parameter 'classType')
Error message
Value cannot be null. (Parameter 'classType')
What it means
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.
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
Example fix
// before EventManager.RegisterClassHandler<Button>(null, UIElement.MouseMoveEvent, OnMouseMove); // throws // after EventManager.RegisterClassHandler<Button>(typeof(Button), UIElement.MouseMoveEvent, OnMouseMove);
Defensive patterns
Strategy: validation
Validate before calling
if (classType == null || routedEvent == null || handler == null)
throw new ArgumentException("classType, routedEvent and handler are required"); Type guard
bool CanRegisterHandler(Type classType) => classType != null;
Try / catch
try
{
EventManager.RegisterClassHandler<T>(classType, routedEvent, handler);
}
catch (ArgumentNullException ex) when (ex.ParamName == "classType")
{
// type could not be resolved; fix bootstrap order or type name
} Prevention
- Use typeof(T) literals for class handlers
- Null-check reflection-resolved types before registration
- Register handlers after all plugin types are loaded
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- A Gear constraint always needs two rigidbodies to be…
- adapter
- antialiasShaderName
- ArgumentNullException: deletedObjects
- ArgumentNullException: dependencyManager
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/0abe4773b7471a2a.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.UI/Events/EventManager.cs:77
types.Add(currentType);
currentType = currentType.GetTypeInfo().BaseType;
}
return types.Where(t => OwnerToEvents.ContainsKey(t)).SelectMany(t => OwnerToEvents[t].Values).ToArray();
}
/// <summary>
/// Registers a class handler for a particular routed event, with the option to handle events where event data is already marked handled.
/// </summary>
/// <param name="classType">The type of the class that is declaring class handling.</param>
/// <param name="routedEvent">The routed event identifier of the event to handle.</param>
/// <param name="handler">A reference to the class handler implementation.</param>
/// <param name="handledEventsToo">true to invoke this class handler even if arguments of the routed event have been marked as handled;
/// false to retain the default behavior of not invoking the handler on any marked-handled event.</param>
/// <exception cref="ArgumentNullException"><paramref name="classType"/>, <paramref name="routedEvent"/>, or <paramref name="handler"/> is null.</exception>
public static void RegisterClassHandler<T>(Type classType, RoutedEvent<T> routedEvent, EventHandler<T> handler, bool handledEventsToo = false) where T : RoutedEventArgs
{
if (classType == null) throw new ArgumentNullException(nameof(classType));
if (routedEvent == null) throw new ArgumentNullException(nameof(routedEvent));
if (handler == null) throw new ArgumentNullException(nameof(handler));
lock(SyncRoot)
{
if (!ClassesToClassHandlers.ContainsKey(classType))
ClassesToClassHandlers[classType] = new Dictionary<RoutedEvent, RoutedEventHandlerInfo>();
ClassesToClassHandlers[classType][routedEvent] = new RoutedEventHandlerInfo<T>(handler, handledEventsToo);
}
}
/// <summary>
/// Get the class handler for the class <paramref name="classType"/> and routed event <paramref name="routedEvent"/>.
/// </summary>
/// <param name="classType">The type of the class that is handling the event.</param>
/// <param name="routedEvent">The routed event to handle</param>
/// <returns>The class handler</returns>View on GitHub (pinned to 96fad776d2)