{"record":{"id":"7d3c80ab838fba26","repo":"stride3d/stride","slug":"the-routed-event-cannot-be-changed-while-the-event-is-being","errorCode":null,"errorMessage":"The routed event cannot be changed while the event is being routed.","messagePattern":"The routed event cannot be changed while the event is being routed\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.UI/Events/RoutedEventArgs.cs","lineNumber":33,"sourceCode":"        public bool Handled { get; set; }\n\n        private RoutedEvent routedEvent;\n\n        private UIElement source;\n\n        protected bool IsBeingRouted { get; private set; }\n\n        /// <summary>\n        /// Gets or sets the <see cref=\"RoutedEvent\"/> associated with this RoutedEventArgs instance.\n        /// </summary>\n        /// <exception cref=\"InvalidOperationException\">Attempted to change the RoutedEvent value while the event is being routed.</exception>\n        public RoutedEvent RoutedEvent \n        {\n            get { return routedEvent; }\n            set\n            {\n                if (IsBeingRouted)\n                    throw new InvalidOperationException(\"The routed event cannot be changed while the event is being routed.\");\n\n                routedEvent = value;\n            }\n        }\n\n        /// <summary>\n        /// Gets or sets a reference to the object that raised the event.\n        /// </summary>\n        /// <exception cref=\"InvalidOperationException\">Attempted to change the source value while the event is being routed.</exception>\n        public UIElement Source \n        {\n            get { return source; }\n            set\n            {\n                if (IsBeingRouted)\n                    throw new InvalidOperationException(\"The routed event cannot be changed while the event is being routed.\");\n\n                source = value;","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.UI/Events/RoutedEventArgs.cs#L15-L51","documentation":"RoutedEventArgs.RoutedEvent setter throws InvalidOperationException if the arguments are currently being routed (IsBeingRouted is true). The routing engine relies on the event identity staying stable while it walks the element tree, so mutating it mid-route would corrupt the routing pass.","triggerScenarios":"Assigning args.RoutedEvent = someEvent from inside a routed-event handler or from code running during RaiseEvent, while the same RoutedEventArgs instance is in flight.","commonSituations":"Handler code that tries to 'retarget' the event to another RoutedEvent; framework/library callbacks invoked during routing that reuse the same args object; helper methods called synchronously from handlers.","solutions":["Raise a new event with a fresh RoutedEventArgs instance instead of mutating the in-flight one","Defer the change until after routing completes (e.g. Dispatcher.InvokeAsync)","If you need different event data, create a new RoutedEventArgs subclass instance per RaiseEvent call"],"exampleFix":"// before\nvoid OnTap(object sender, RoutedEventArgs e)\n{\n    e.RoutedEvent = DoubleTapEvent; // throws while routing\n    element.RaiseEvent(e);\n}\n// after\nvoid OnTap(object sender, RoutedEventArgs e)\n{\n    var newArgs = new RoutedEventArgs(DoubleTapEvent) { Source = element };\n    element.RaiseEvent(newArgs);\n}","handlingStrategy":"validation","validationCode":"if (args.IsBeingRouted) throw new InvalidOperationException(\"Cannot change RoutedEvent while routing\");","typeGuard":"static bool CanMutate(RoutedEventArgs args) => args != null && !args.IsBeingRouted;","tryCatchPattern":"try { args.RoutedEvent = newEvent; }\ncatch (InvalidOperationException) { var fresh = new RoutedEventArgs(newEvent) { Source = args.Source }; target.RaiseEvent(fresh); }","preventionTips":["Never mutate RoutedEventArgs inside handlers; create new args for new events","Treat in-flight routed args as read-only","Use Dispatcher.InvokeAsync to defer mutations until after routing"],"tags":["csharp","ui","events","invalid-state"],"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"}