dotnet/wpf · error · InvalidOperationException

SR.Invalid_IInputElement (newFocus.GetType())

Error message

SR.Invalid_IInputElement (newFocus.GetType())

What it means

The KeyboardFocusChangedEventArgs constructor validates newFocus via InputElement.IsValid and throws InvalidOperationException(SR.Invalid_IInputElement, newFocus.GetType()) when newFocus is non-null but not a type WPF's keyboard system accepts (a UIElement-derived or ContentElement-derived element). Directly implementing IInputElement is not sufficient.

Solutions

  1. Ensure newFocus is an instance of UIElement or ContentElement (or derived class).
  2. Pass null when there is no new focus target.
  3. Call InputElement.IsValid(newFocus) before constructing the args and handle invalid values.
  4. In tests, create real FrameworkElement instances instead of IInputElement mocks.

Example fix

// before
IInputElement newFocus = Substitute.For<IInputElement>();
var args = new KeyboardFocusChangedEventArgs(kb, ts, oldFocus, newFocus);
// after
IInputElement newFocus = new Border(); // real UIElement
var args = new KeyboardFocusChangedEventArgs(kb, ts, oldFocus, newFocus);
Defensive patterns

Strategy: type-guard

Validate before calling

if (newFocus != null && newFocus is not (UIElement or ContentElement))
    throw new InvalidOperationException($"newFocus must be UIElement/ContentElement, got {newFocus.GetType()}");

Type guard

static bool IsValidFocusTarget(IInputElement e) => e is null or UIElement or ContentElement;

Try / catch

try { args = new KeyboardFocusChangedEventArgs(kb, ts, oldFocus, newFocus); }
catch (InvalidOperationException ex)
{ logger.LogError("Bad newFocus: {Msg}", ex.Message); return; }

Prevention

When it happens

Trigger: new KeyboardFocusChangedEventArgs(keyboard, timestamp, oldFocus, newFocus) with a non-null newFocus that is a hand-rolled IInputElement implementation or an unrelated object cast to IInputElement.

Common situations: Simulating keyboard focus in automation/tests with fake objects; passing proxy/wrapper objects around real visuals; interop code supplying non-WPF elements.

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


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/FocusChangedEventArgs.cs:32

        /// <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.
        /// </summary>
        public IInputElement NewFocus
        {

View on GitHub (pinned to 81131a70a4)