{"record":{"id":"ef70d64028022cc3","repo":"dotnet/wpf","slug":"sr-handlertypeillegal-uielement","errorCode":null,"errorMessage":"SR.HandlerTypeIllegal","messagePattern":"SR\\.HandlerTypeIllegal","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Generated/UIElement.cs","lineNumber":521,"sourceCode":"        /// </param>\n        /// <param name=\"handledEventsToo\">\n        ///     Flag indicating whether or not the listener wants to\n        ///     hear about events that have already been handled\n        /// </param>\n        public void AddHandler(\n            RoutedEvent routedEvent,\n            Delegate handler,\n            bool handledEventsToo)\n        {\n            // VerifyAccess();\n\n            ArgumentNullException.ThrowIfNull(routedEvent);\n\n            ArgumentNullException.ThrowIfNull(handler);\n\n            if (!routedEvent.IsLegalHandler(handler))\n            {\n                throw new ArgumentException(SR.HandlerTypeIllegal);\n            }\n\n            EnsureEventHandlersStore();\n            EventHandlersStore.AddRoutedEventHandler(routedEvent, handler, handledEventsToo);\n\n            OnAddHandler(routedEvent, handler);\n        }\n\n        /// <summary>\n        ///     Notifies subclass of a new routed event handler.  Note that this is\n        ///     called once for each handler added, but OnRemoveHandler is only called\n        ///     on the last removal.\n        /// </summary>\n        internal virtual void OnAddHandler(\n            RoutedEvent routedEvent,\n            Delegate handler)\n        {\n        }","sourceCodeStart":503,"sourceCodeEnd":539,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Generated/UIElement.cs#L503-L539","documentation":"UIElement.AddHandler throws ArgumentException with SR.HandlerTypeIllegal when the supplied handler delegate is not of a type the routed event considers legal. RoutedEvent.IsLegalHandler checks that the handler's type matches the event's registered handler type (e.g. RoutedEventHandler) or is a compatible delegate. This prevents wiring a delegate with the wrong signature to a routed event, which would fail at invoke time.","triggerScenarios":"Calling uiElement.AddHandler(routedEvent, handler) where handler is a Delegate whose type is not compatible with routedEvent.HandlerType — e.g. passing a MyCustomEventHandler delegate to an event registered for RoutedEventHandler, or passing a generic/unrelated delegate instance.","commonSituations":"Developers create a custom routed event with a specific handler type but then attach a generic RoutedEventHandler or a lambda cast to the wrong delegate type; refactors change the handler type of a RoutedEvent.Register call but old call sites still use the old delegate type.","solutions":["Use a handler delegate whose type exactly matches the type the RoutedEvent was registered with (the handlerType argument to RoutedEvent.Register).","If you intended the generic handler, use RoutedEvent.AddHandler(owner, handler) overload semantics or re-register the event with RoutedEventHandler as its handler type.","Use the CLR event wrapper (e.g. element.MouseDown += Handler) and let the compiler enforce the delegate type.","Verify routedEvent.HandlerType at runtime if the event is received dynamically, and construct the handler via Delegate.CreateDelegate with that type."],"exampleFix":"// before\nvar handler = new EventHandler((s, e) => { });\nelem.AddHandler(MyControl.MyCustomEvent, handler); // ArgumentException\n// after\nvar handler = new MyCustomRoutedEventHandler((s, e) => { });\nelem.AddHandler(MyControl.MyCustomEvent, handler);","handlingStrategy":"validation","validationCode":"if (routedEvent == null) throw new ArgumentNullException(nameof(routedEvent));\nif (handler == null) throw new ArgumentNullException(nameof(handler));\nif (!routedEvent.IsLegalHandler(handler))\n    throw new ArgumentException($\"Handler must be of type {routedEvent.HandlerType} for this routed event.\");","typeGuard":"static bool IsLegalFor(RoutedEvent ev, Delegate h) => h != null && ev != null && ev.IsLegalHandler(h);","tryCatchPattern":"try { element.AddHandler(routedEvent, handler); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"HandlerTypeIllegal\") || ex.ParamName == null) { /* log wrong delegate type, use correct handler type */ }","preventionTips":["Always use the CLR event +=/-= accessors when available so the compiler enforces the delegate type","Check the handlerType passed to RoutedEvent.Register when writing custom events","Never cast delegates across unrelated handler types"],"tags":["wpf","routed-events","argumentexception"],"backgroundTag":"invalid-argument-value","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}