dotnet/wpf · error · ArgumentException

SR.Automation_InvalidEventId

Error message

SR.Automation_InvalidEventId

What it means

EventMap.GetRegisteredEventObjectHelper maps an AutomationEvents enum value to the corresponding UIA event identifier. If the eventId is not one of the known enum cases, the method throws ArgumentException with SR.Automation_InvalidEventId. This guards the internal event registration table against unknown event ids.

Solutions

  1. Use only valid AutomationEvents members (e.g. AutomationEvents.AutomationFocusChanged); never cast raw ints into the enum.
  2. Check the enum value with Enum.IsDefined(typeof(AutomationEvents), value) before raising.
  3. Rebuild against the matching WindowsBase/PresentationCore versions so the enum and event map agree.
  4. In custom peer code, switch on the enum and let unknown values fall through without throwing.

Example fix

// before
peer.RaiseAutomationEvent((AutomationEvents)99);
// after
var eventId = AutomationEvents.LiveRegionChanged;
if (Enum.IsDefined(typeof(AutomationEvents), eventId))
{
    peer.RaiseAutomationEvent(eventId);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!Enum.IsDefined(typeof(AutomationEvents), eventId))
    throw new ArgumentOutOfRangeException(nameof(eventId));

Type guard

bool IsValidAutomationEvent(AutomationEvents e) => Enum.IsDefined(typeof(AutomationEvents), e);

Try / catch

try
{
    peer.RaiseAutomationEvent(eventId);
}
catch (ArgumentException ex) when (ex.ParamName == "eventId")
{
    // log invalid event id and skip raise
}

Prevention

When it happens

Trigger: Calling RaiseAutomationEvent / HasRegisteredEvent / GetRegisteredEvent with an AutomationEvents value outside the defined enum range — e.g. an invalid cast, a value from a newer/older framework version, or uninitialized/default misuse.

Common situations: Custom control authors raising automation events with a hand-crafted or wrongly cast enum value; assembly/version mismatch where an AutomationEvents member exists on one side but not the mapped table; reflection-driven code passing raw ints as the enum.

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/9fd116930e0c02ee. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Automation/EventMap.cs:110

                case AutomationEvents.InvokePatternOnInvoked:                               eventObject = InvokePatternIdentifiers.InvokedEvent; break;
                case AutomationEvents.SelectionItemPatternOnElementAddedToSelection:        eventObject = SelectionItemPatternIdentifiers.ElementAddedToSelectionEvent; break;
                case AutomationEvents.SelectionItemPatternOnElementRemovedFromSelection:    eventObject = SelectionItemPatternIdentifiers.ElementRemovedFromSelectionEvent; break;
                case AutomationEvents.SelectionItemPatternOnElementSelected:                eventObject = SelectionItemPatternIdentifiers.ElementSelectedEvent; break;
                case AutomationEvents.SelectionPatternOnInvalidated:                        eventObject = SelectionPatternIdentifiers.InvalidatedEvent; break;
                case AutomationEvents.TextPatternOnTextSelectionChanged:                    eventObject = TextPatternIdentifiers.TextSelectionChangedEvent; break;
                case AutomationEvents.TextPatternOnTextChanged:                             eventObject = TextPatternIdentifiers.TextChangedEvent; break;
                case AutomationEvents.AsyncContentLoaded:                                   eventObject = AutomationElementIdentifiers.AsyncContentLoadedEvent; break;
                case AutomationEvents.PropertyChanged:                                      eventObject = AutomationElementIdentifiers.AutomationPropertyChangedEvent; break;
                case AutomationEvents.StructureChanged:                                     eventObject = AutomationElementIdentifiers.StructureChangedEvent; break;
                case AutomationEvents.InputReachedTarget:                                   eventObject = SynchronizedInputPatternIdentifiers.InputReachedTargetEvent; break;
                case AutomationEvents.InputReachedOtherElement:                             eventObject = SynchronizedInputPatternIdentifiers.InputReachedOtherElementEvent; break;
                case AutomationEvents.InputDiscarded:                                       eventObject = SynchronizedInputPatternIdentifiers.InputDiscardedEvent; break;
                case AutomationEvents.LiveRegionChanged:                                    eventObject = AutomationElementIdentifiers.LiveRegionChangedEvent; break;
                case AutomationEvents.Notification:                                         eventObject = AutomationElementIdentifiers.NotificationEvent; break;
                case AutomationEvents.ActiveTextPositionChanged:                            eventObject = AutomationElementIdentifiers.ActiveTextPositionChangedEvent; break;

                default:
                    throw new ArgumentException(SR.Automation_InvalidEventId, nameof(eventId));
            }

            if ((eventObject != null) && (!_eventsTable.ContainsKey(eventObject.Id)))
            {
                eventObject = null;
            }

            return (eventObject);
        }

        internal static void AddEvent(int idEvent)
        {
            //  to avoid unbound memory allocations,
            //  register only events that we recognize
            if (IsKnownEvent(idEvent))
            {
                bool firstEvent = false;
                lock (_lock)

View on GitHub (pinned to 81131a70a4)