dotnet/wpf · error · InvalidEnumArgumentException

InvalidEnumArgumentException("key", (int)key, typeof(Key))

Error message

InvalidEnumArgumentException("key", (int)key, typeof(Key))

What it means

InvalidEnumArgumentException from KeyboardDevice.Validate_Key: because Enum.IsDefined is proscribed for performance, the private validator manually checks the Key value and rejects any key whose integer value is >= 256 or negative, i.e. not a member of the Key enumeration.

Solutions

  1. Skip or special-case Key.None (0) before querying key state
  2. Clamp/validate: if ((int)key > 0 && (int)key < 256) before calling, or use Keyboard.IsValidKey
  3. Fix the virtual-key-to-Key conversion so it never yields 0 or >255

Example fix

// before
bool down = Keyboard.IsKeyDown((Key)vk);
// after
Key k = (Key)vk;
bool down = vk != 0 && Keyboard.IsKeyDown(k);
Defensive patterns

Strategy: validation

Validate before calling

bool keyInRange = (int)key > 0 && (int)key < 256;

Type guard

bool IsQueryableKey(Key k) => (int)k > 0 && (int)k < 256;

Try / catch

try { var st = Keyboard.GetKeyStates(key); } catch (InvalidEnumArgumentException) { /* Key.None or out-of-range */ }

Prevention

When it happens

Trigger: Calling Keyboard.IsKeyDown/IsKeyUp/IsKeyToggled/GetKeyStates with Key.None (0) or a key >= 256 (cast from raw int or undefined enum member).

Common situations: Interop code mapping virtual-key codes directly into Key without adjusting for the Key enum's 1-based layout; iterating a range that includes Key.None; deserialized/binary data containing 0.

Understand the failure class

Background: "invalid argument", "unknown mode", "not supported": invalid enum-like argument errors explained — this error's family across 19 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/KeyboardDevice.cs:205

                    modifiers |= ModifierKeys.Control;
                }
                if(IsKeyDown_private(Key.LeftShift) || IsKeyDown_private(Key.RightShift))
                {
                    modifiers |= ModifierKeys.Shift;
                }

                return modifiers;
            }
        }

        /// <summary>
        /// There is a proscription against using Enum.IsDefined().  (it is slow)
        /// so we write these PRIVATE validate routines instead.
        /// </summary>
        private void Validate_Key(Key key)
        {
            if( 256 <= (int)key || (int)key <= 0)
                throw new  System.ComponentModel.InvalidEnumArgumentException("key", (int)key, typeof(Key));
        }

        /// <summary>
        /// This is the core private method that returns whether or not the specified key
        ///  is down.  It does it without the extra argument validation and context checks.
        /// </summary>
        private bool IsKeyDown_private(Key key)
        {
            return ( ( GetKeyStatesFromSystem(key) & KeyStates.Down ) == KeyStates.Down );
        }

        /// <summary>
        ///     Returns whether or not the specified key is down.
        /// </summary>
        public bool IsKeyDown(Key key)
        {
//             VerifyAccess();
            Validate_Key(key);

View on GitHub (pinned to 81131a70a4)