dotnet/wpf · error · InvalidOperationException

SR.Format(SR.Invalid_IInputElement, o.GetType())

Error message

SR.Format(SR.Invalid_IInputElement, o.GetType())

What it means

Inside AddSourceChangedHandler, after the top-level type check, the element is dispatched by concrete type (UIElement, ContentElement, UIElement3D). If the object somehow passes InputElement.IsValid yet matches none of these three concrete classes, an InvalidOperationException is thrown - an internal invariant fallback.

Solutions

  1. Ensure only UIElement, ContentElement, or UIElement3D instances are subscribed.
  2. Verify all WPF assemblies resolve to the same version to avoid type-identity mismatches.
  3. Replace custom element base classes with the standard WPF element classes.
  4. If unavoidable, subscribe at a known UIElement ancestor instead of the exotic element.

Example fix

// before
PresentationSource.AddSourceChangedHandler(customElementBase, handler);

// after
PresentationSource.AddSourceChangedHandler((UIElement)customElementBase, handler);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(o is UIElement || o is ContentElement || o is UIElement3D)) return;

Type guard

static bool IsKnownInputElement(DependencyObject o) =>
    o is UIElement || o is ContentElement || o is UIElement3D;

Prevention

When it happens

Trigger: Passing an element type for which the type-switch has no case (a type recognized as valid IInputElement but not one of the three known classes) - typically only possible with exotic third-party implementations of the internal input contracts.

Common situations: Using framework versions where new IInputElement implementers exist but the switch in PresentationSource was not updated; custom frameworks reimplementing core element types; assembly-mix mismatches between WPF assemblies (e.g. different PresentationCore versions loaded).

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/PresentationSource.cs:163

                    info = uie3D.EventHandlersStore[SourceChangedEvent];
                    if (1 == info.Count)
                    {
                        uie3D.VisualAncestorChanged += new Visual.AncestorChangedEventHandler(uie3D.OnVisualAncestorChanged);
                        AddElementToWatchList(uie3D);
                    }
                }
                else if (o is ContentElement ce)
                {
                    ce.AddHandler(SourceChangedEvent, handler);
                    info = ce.EventHandlersStore[SourceChangedEvent];
                    if (1 == info.Count)
                    {
                        AddElementToWatchList(ce);
                    }
                }
                else
                {
                    throw new InvalidOperationException(SR.Format(SR.Invalid_IInputElement, o.GetType())); 
                }
            }
        }

        /// <summary>
        ///     Removes a handler for the SourceChanged event to the element.
        /// </summary>
        /// <param name="e">The element to remove the handler from.</param>
        /// <param name="handler">The hander to remove.</param>
        /// <remarks>
        ///     Even though this is a routed event handler, there are special
        ///     restrictions placed on this event.
        ///     1) You cannot use the UIElement or ContentElement RemoveHandler() method.
        /// </remarks>
        public static void RemoveSourceChangedHandler(IInputElement e, SourceChangedEventHandler handler)
        {
            ArgumentNullException.ThrowIfNull(e);

View on GitHub (pinned to 81131a70a4)