dotnet/wpf · error · InvalidEnumArgumentException

InvalidEnumArgumentException: routingStrategy

Error message

InvalidEnumArgumentException: routingStrategy

What it means

EventManager.RegisterRoutedEvent requires routingStrategy to be one of Tunnel, Bubble, or Direct. Any other value of the RoutingStrategy enum triggers InvalidEnumArgumentException naming the parameter 'routingStrategy'. This guards against invalid enum casts at the public registration API.

Solutions

  1. Pass a valid RoutingStrategy: Tunnel, Bubble, or Direct
  2. Validate/whitelist the int source value with Enum.IsDefined before casting
  3. Fix the code that produced the out-of-range enum value

Example fix

// before
var strategy = (RoutingStrategy)userValue; // e.g. 7
EventManager.RegisterRoutedEvent("MyEvent", strategy, typeof(EventHandler), typeof(MyControl));
// after
if (Enum.IsDefined(typeof(RoutingStrategy), userValue))
    EventManager.RegisterRoutedEvent("MyEvent", (RoutingStrategy)userValue, typeof(EventHandler), typeof(MyControl));
else
    EventManager.RegisterRoutedEvent("MyEvent", RoutingStrategy.Bubble, typeof(EventHandler), typeof(MyControl));
Defensive patterns

Strategy: validation

Validate before calling

if (Enum.IsDefined(typeof(RoutingStrategy), routingStrategy)) { /* safe */ }

Type guard

bool IsValidRoutingStrategy(RoutingStrategy s) => s is RoutingStrategy.Tunnel or RoutingStrategy.Bubble or RoutingStrategy.Direct;

Try / catch

try { EventManager.RegisterRoutedEvent(name, strategy, handlerType, ownerType); } catch (InvalidEnumArgumentException) { strategy = RoutingStrategy.Bubble; }

Prevention

When it happens

Trigger: Calling RegisterRoutedEvent with a RoutingStrategy value obtained via an unchecked cast, e.g. (RoutingStrategy)99, or a default/uninitialized enum value.

Common situations: Reading the strategy from configuration or data where it was stored as int; reflection-driven event registration; deserialization assigning numeric enum values.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/EventManager.cs:61

        ///     <see cref="RoutedEvent.OwnerType"/>
        /// </param>
        /// <returns>
        ///     The new registered <see cref="RoutedEvent"/>
        /// </returns>
        /// <ExternalAPI/>
        public static RoutedEvent RegisterRoutedEvent(
            string name,
            RoutingStrategy routingStrategy,
            Type handlerType,
            Type ownerType)
        {
            ArgumentNullException.ThrowIfNull(name);

            if (routingStrategy != RoutingStrategy.Tunnel && 
                routingStrategy != RoutingStrategy.Bubble &&
                routingStrategy != RoutingStrategy.Direct) 
            {
                throw new System.ComponentModel.InvalidEnumArgumentException("routingStrategy", (int)routingStrategy, typeof(RoutingStrategy));
            }

            ArgumentNullException.ThrowIfNull(handlerType);

            ArgumentNullException.ThrowIfNull(ownerType);

            if (GlobalEventManager.GetRoutedEventFromName(name, ownerType, false) != null)
            {
                throw new ArgumentException(SR.Format(SR.DuplicateEventName, name, ownerType)); 
            }

            return GlobalEventManager.RegisterRoutedEvent(name, routingStrategy, handlerType, ownerType);
        }

        /// <summary>
        ///     See overloaded method for details
        /// </summary>
        /// <remarks>

View on GitHub (pinned to 81131a70a4)