{"record":{"id":"2954bee3ffcd1c21","repo":"stride3d/stride","slug":"a-routed-event-named-name-already-exists-in-provided-owner","errorCode":null,"errorMessage":"A routed event named '{name}' already exists in provided owner type '{ownerType}' or base classes.","messagePattern":"A routed event named '(.+?)' already exists in provided owner type '(.+?)' or base classes\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.UI/Events/EventManager.cs","lineNumber":135,"sourceCode":"        /// <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        }\n\n        private static readonly List<RoutedEvent> RoutedEvents = new List<RoutedEvent>();\n        private static readonly Dictionary<Type, Dictionary<string, RoutedEvent>> OwnerToEvents = new Dictionary<Type, Dictionary<string, RoutedEvent>>();\n ","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.UI/Events/EventManager.cs#L117-L153","documentation":"RegisterRoutedEvent<T> enforces globally unique routed event names per owner type (including base classes). If GetRoutedEvent(ownerType, name) finds an existing event, registration is rejected with InvalidOperationException to prevent ambiguous event identifiers in the routing system.","triggerScenarios":"Calling EventManager.RegisterRoutedEvent twice with the same (name, ownerType) pair — e.g. duplicate static registration code, the same event inherited from a base class, or a control defined in two assemblies both registering the same name.","commonSituations":"See trigger scenarios.","solutions":["Remove the duplicate RegisterRoutedEvent call and reuse the existing static RoutedEvent<T> field","Rename your event to a unique name within the owner type hierarchy","Check base classes for an existing event of the same name before registering"],"exampleFix":"// before\npublic static readonly RoutedEvent<RoutedEventArgs> TapEvent =\n    EventManager.RegisterRoutedEvent<RoutedEventArgs>(\"Tap\", RoutingStrategy.Bubble, typeof(MyButton)); // also registered in base\n// after\npublic static readonly RoutedEvent<RoutedEventArgs> TapEvent =\n    BaseControl.TapEvent; // reuse existing registration","handlingStrategy":"validation","validationCode":"if (EventManager.GetRoutedEvent<RoutedEventArgs>(ownerType, name) != null)\n    throw new InvalidOperationException($\"Event '{name}' already registered for {ownerType}\");","typeGuard":null,"tryCatchPattern":"try { evt = EventManager.RegisterRoutedEvent<T>(name, strategy, ownerType); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"already exists\")) { evt = EventManager.GetRoutedEvent<RoutedEventArgs>(ownerType, name); }","preventionTips":["Register each routed event exactly once in a static readonly field","Check base classes for same-named events before adding new ones","Namespace event names uniquely across shared control libraries"],"tags":["csharp","duplicate-registration","ui","events"],"backgroundTag":"invalid-state-transition","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"}