dotnet/wpf · error · InvalidOperationException
SR.Invalid_IInputElement (oldFocus.GetType())
Error message
SR.Invalid_IInputElement (oldFocus.GetType())
What it means
The KeyboardFocusChangedEventArgs constructor validates oldFocus via InputElement.IsValid and throws InvalidOperationException(SR.Invalid_IInputElement, oldFocus.GetType()) if it is non-null but is not a valid IInputElement — i.e. it is neither a ContentElement, nor a UIElement (or its valid subclasses) that WPF's input system can target. The keyboard input system can only raise focus events against these element types.
Solutions
- Derive the focus element from UIElement (or ContentElement for document content) instead of implementing IInputElement directly.
- Pass null if there is no previous focus element rather than a placeholder object.
- Use InputElement.IsValid(element) in a guard before constructing the event args.
- Replace test mocks with real UIElement instances or derived test doubles.
Example fix
// before
class MyFocusTarget : IInputElement { ... }
var args = new KeyboardFocusChangedEventArgs(kb, ts, new MyFocusTarget(), newFocus);
// after
class MyFocusTarget : UIElement { ... }
var args = new KeyboardFocusChangedEventArgs(kb, ts, new MyFocusTarget(), newFocus); Defensive patterns
Strategy: type-guard
Validate before calling
if (oldFocus != null && !InputElement.IsValid(oldFocus))
throw new InvalidOperationException($"Invalid focus element: {oldFocus.GetType()}"); Type guard
static bool IsValidFocusElement(IInputElement e) => e is null || InputElement.IsValid(e); // or without internals: e is UIElement or e is ContentElement
Try / catch
try { args = new KeyboardFocusChangedEventArgs(kb, ts, oldFocus, newFocus); }
catch (InvalidOperationException ex)
{ logger.LogError("Invalid focus element: {Msg}", ex.Message); args = null; } Prevention
- Derive focus targets from UIElement/ContentElement, never hand-implement IInputElement.
- Pass null instead of placeholder objects for 'no previous focus'.
- In tests, use real FrameworkElement instances rather than IInputElement mocks.
- Validate elements with InputElement.IsValid (or a UIElement/ContentElement pattern check) before use.
When it happens
Trigger: new KeyboardFocusChangedEventArgs(keyboard, timestamp, oldFocus, newFocus) with a non-null oldFocus that is a custom object implementing IInputElement directly instead of deriving from UIElement/ContentElement.
Common situations: Custom framework classes implementing IInputElement manually; passing mock objects in unit tests; passing elements from a different presentation source or a non-WPF object that merely implements the interface.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- SR.Invalid_IInputElement (newFocus.GetType())
- InvalidEnumArgumentException("mode", (int)mode…
- InvalidEnumArgumentException("type", (int)type…
- Animation_ChildMustBeKeyFrame
- Animation_DependencyPropertyIsNotAnimatable
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/fd58efceef00a665.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/FocusChangedEventArgs.cs:29
/// <summary>
/// Constructs an instance of the KeyboardFocusChangedEventArgs class.
/// </summary>
/// <param name="keyboard">
/// The logical keyboard device associated with this event.
/// </param>
/// <param name="timestamp">
/// The time when the input occurred.
/// </param>
/// <param name="oldFocus">
/// The element that previously had focus.
/// </param>
/// <param name="newFocus">
/// The element that now has focus.
/// </param>
public KeyboardFocusChangedEventArgs(KeyboardDevice keyboard, int timestamp, IInputElement oldFocus, IInputElement newFocus) : base(keyboard, timestamp)
{
if (oldFocus != null && !InputElement.IsValid(oldFocus))
throw new InvalidOperationException(SR.Format(SR.Invalid_IInputElement, oldFocus.GetType()));
if (newFocus != null && !InputElement.IsValid(newFocus))
throw new InvalidOperationException(SR.Format(SR.Invalid_IInputElement, newFocus.GetType()));
_oldFocus = oldFocus;
_newFocus = newFocus;
}
/// <summary>
/// The element that previously had focus.
/// </summary>
public IInputElement OldFocus
{
get {return _oldFocus;}
}
/// <summary>
/// The element that now has focus.View on GitHub (pinned to 81131a70a4)