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
- Ensure only UIElement, ContentElement, or UIElement3D instances are subscribed.
- Verify all WPF assemblies resolve to the same version to avoid type-identity mismatches.
- Replace custom element base classes with the standard WPF element classes.
- 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
- Ensure all WPF assemblies are the same version (check binding redirects).
- Avoid third-party re-implementations of WPF core element types.
- Subscribe only on standard WPF element classes.
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
- ' ' is not a Visual or Visual3D.
- 0x80070057
- Animation_AnimationTimelineTypeMismatch
- Property data must be a non-reference variant compatible…
- Property is not a valid instance of PrintTicket.
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)