dotnet/wpf · error · ArgumentException

SR.SourceNotSet

Error message

SR.SourceNotSet

What it means

EventRoute.InvokeHandlersImpl requires the RoutedEventArgs to have its Source set before the route can be raised. If args.Source is null it throws ArgumentException with SR.SourceNotSet. Source is used to start/continue route traversal, so an unset source makes routing impossible.

Solutions

  1. Set args.Source (or call args.SetSource / raise via UIElement.RaiseEvent which sets Source) before invoking the route
  2. Ensure custom event args constructors assign a non-null Source
  3. Route the event through element.RaiseEvent rather than manual EventRoute invocation

Example fix

// before
var args = new RoutedEventArgs(MyEvent);
route.InvokeHandlers(this, args);
// after
var args = new RoutedEventArgs(MyEvent);
args.Source = sourceElement;
route.InvokeHandlers(this, args);
Defensive patterns

Strategy: validation

Validate before calling

if (args != null && args.Source != null) { route.InvokeHandlers(this, args); }

Type guard

bool HasSource(RoutedEventArgs a) => a != null && a.Source != null;

Try / catch

try { route.InvokeHandlers(this, args); } catch (ArgumentException) { /* args.Source was null */ }

Prevention

When it happens

Trigger: Invoking the route (via InvokeHandlers/ReInvokeHandlers or RaiseEvent plumbing) with a RoutedEventArgs instance whose Source was never set — e.g. constructing a new RoutedEventArgs and calling route.InvokeHandlers manually without assigning Source.

Common situations: Custom routing code building an EventRoute by hand; re-raising a cloned event args where Source was not copied; unit tests invoking routes directly.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/ebaa8f3517a17801. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/EventRoute.cs:128

        internal void InvokeHandlers(object source, RoutedEventArgs args)
        {
            InvokeHandlersImpl(source, args, false);
        }

        internal void ReInvokeHandlers(object source, RoutedEventArgs args)
        {
            InvokeHandlersImpl(source, args, true);
        }

        private void InvokeHandlersImpl(object source, RoutedEventArgs args, bool reRaised)
        {
            ArgumentNullException.ThrowIfNull(source);

            ArgumentNullException.ThrowIfNull(args);

            if (args.Source == null)
            {
                throw new ArgumentException(SR.SourceNotSet); 
            }

            if (args.RoutedEvent != _routedEvent)
            {
                throw new ArgumentException(SR.Mismatched_RoutedEvent);
            }

            // Check RoutingStrategy to know the order of invocation
            if (args.RoutedEvent.RoutingStrategy == RoutingStrategy.Bubble ||
                args.RoutedEvent.RoutingStrategy == RoutingStrategy.Direct)
            {
                int endSourceChangeIndex = 0;
                
                // If the RoutingStrategy of the associated is 
                // Bubble the handlers for the last target 
                // added are the last ones invoked
                // Invoke class listeners
                for (int i=0; i<_routeItemList.Count; i++)

View on GitHub (pinned to 81131a70a4)