{"record":{"id":"073453ae60c6f1d8","repo":"stride3d/stride","slug":"value-cannot-be-null-parameter-name-eventmanager","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'name')","messagePattern":"Value cannot be null\\. \\(Parameter 'name'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.UI/Events/EventManager.cs","lineNumber":131,"sourceCode":"        }\n\n        private static readonly Dictionary<Type, Dictionary<RoutedEvent, RoutedEventHandlerInfo>> ClassesToClassHandlers = new Dictionary<Type, Dictionary<RoutedEvent, RoutedEventHandlerInfo>>();\n\n        /// <summary>\n        /// Registers a new routed event.\n        /// </summary>\n        /// <param name=\"name\">The name of the routed event. The name must be unique within the owner type (base class included) and cannot be null or an empty string.</param>\n        /// <param name=\"routingStrategy\">The routing strategy of the event as a value of the enumeration.</param>\n        /// <param name=\"ownerType\">The owner class type of the routed event. This cannot be null.</param>\n        /// <returns>The identifier for the newly registered routed event. \n        /// This identifier object can now be stored as a static field in a class and then used as a parameter for methods that attach handlers to the event. \n        /// The routed event identifier is also used for other event system APIs.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"name\"/> or <paramref name=\"ownerType\"/> is null.</exception>\n        /// <exception cref=\"InvalidOperationException\">This exception is thrown if a routed event of name <paramref name=\"name\"/> already exists for type <paramref name=\"ownerType\"/> and parents.\n        /// </exception>\n        public static RoutedEvent<T> RegisterRoutedEvent<T>(string name, RoutingStrategy routingStrategy, Type ownerType) where T: RoutedEventArgs\n        {\n            if (name == null) throw new ArgumentNullException(nameof(name));\n            if (ownerType == null) throw new ArgumentNullException(nameof(ownerType));\n            \n            if (GetRoutedEvent(ownerType, name) != null)\n                throw new InvalidOperationException(\"A routed event named '\" + name + \"' already exists in provided owner type '\" + ownerType + \"' or base classes.\");\n\n            var newRoutedEvent = new RoutedEvent<T> {  Name = name, OwnerType = ownerType, RoutingStrategy = routingStrategy, };\n            lock(SyncRoot)\n            {\n                RoutedEvents.Add(newRoutedEvent);\n\n                if (!OwnerToEvents.ContainsKey(ownerType))\n                    OwnerToEvents[ownerType] = new Dictionary<string, RoutedEvent>();\n\n                OwnerToEvents[ownerType][name] = newRoutedEvent; \n            }\n\n            return newRoutedEvent;\n        }","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.UI/Events/EventManager.cs#L113-L149","documentation":"RegisterRoutedEvent<T> requires a non-null event name because the name is part of the routed event's identity used for lookups (GetRoutedEvent) and duplicate detection. A null name is rejected with ArgumentNullException before any registration state changes.","triggerScenarios":"Calling EventManager.RegisterRoutedEvent<T>(null, routingStrategy, ownerType), usually via a name constant that is null or a config-driven name that failed to load.","commonSituations":"Constants/resource files not loaded at static-ctor time; reflection reading an attribute property that defaults to null; refactoring that removed the string literal.","solutions":["Pass a literal or guaranteed-initialized const string as the event name","Null-check any dynamically sourced name before calling RegisterRoutedEvent","Verify static field initialization order so the name constant is assigned first"],"exampleFix":"// before\nstring evtName = LoadEventName();\nvar evt = EventManager.RegisterRoutedEvent<RoutedEventArgs>(evtName, RoutingStrategy.Bubble, typeof(MyControl));\n// after\nstring evtName = LoadEventName() ?? \"MyCustomEvent\";\nvar evt = EventManager.RegisterRoutedEvent<RoutedEventArgs>(evtName, RoutingStrategy.Bubble, typeof(MyControl));","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(name)) throw new InvalidOperationException(\"Event name must be a non-empty string\");","typeGuard":"static bool ValidEventName(string name) => !string.IsNullOrWhiteSpace(name);","tryCatchPattern":"try { return EventManager.RegisterRoutedEvent<T>(name, strategy, ownerType); }\ncatch (ArgumentNullException ex) { throw new InvalidOperationException($\"Bad routed event name '{name}'\", ex); }","preventionTips":["Use const string literals for event names","Avoid sourcing event names from config or reflection without validation","Register events in static constructors with fixed names"],"tags":["csharp","null-argument","ui","events"],"backgroundTag":"null-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"}