dotnet/wpf · error · InvalidEnumArgumentException

InvalidEnumArgumentException("modifiers", (int)modifiers…

Error message

InvalidEnumArgumentException("modifiers", (int)modifiers, typeof(ModifierKeys))

What it means

The private KeyGesture constructor validates that the ModifierKeys value is a defined combination (via ModifierKeysConverter.IsDefinedModifierKeys) and throws InvalidEnumArgumentException for 'modifiers' otherwise. This catches out-of-range or undefined bit values cast into ModifierKeys.

Solutions

  1. Only pass ModifierKeys values composed of the defined enum members (None, Alt, Control, Shift, Windows)
  2. Validate with ModifierKeysConverter.IsDefinedModifierKeys before constructing
  3. Clamp/parse modifiers from config through the enum converter rather than raw casts

Example fix

// before
var gesture = new KeyGesture(Key.A, (ModifierKeys)rawInt);
// after
var modifiers = (ModifierKeys)rawInt;
if (ModifierKeysConverter.IsDefinedModifierKeys(modifiers))
{
    var gesture = new KeyGesture(Key.A, modifiers);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!ModifierKeysConverter.IsDefinedModifierKeys(modifiers)) throw new ArgumentOutOfRangeException(nameof(modifiers));

Type guard

static bool IsDefinedModifiers(ModifierKeys m) => ModifierKeysConverter.IsDefinedModifierKeys(m);

Try / catch

try { var g = new KeyGesture(key, modifiers); } catch (InvalidEnumArgumentException ex) { /* undefined modifiers value */ }

Prevention

When it happens

Trigger: Calling a public KeyGesture constructor with (ModifierKeys)value where the int is not a defined enum combination (e.g. (ModifierKeys)99 or negative values).

Common situations: Deserializing gestures from config where modifier ints come from user data or another system's flag values.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Command/KeyGesture.cs:91

        /// <param name="key">Key</param>
        /// <param name="modifiers">Modifiers</param>
        /// <param name="validateGesture">If true, throws an exception if the key and modifier are not valid</param>
        internal KeyGesture(Key key, ModifierKeys modifiers, bool validateGesture)
            : this(key, modifiers, String.Empty, validateGesture)
        {
        }

        /// <summary>
        /// Private constructor that does the real work.
        /// </summary>
        /// <param name="key">Key</param>
        /// <param name="modifiers">Modifiers</param>
        /// <param name="displayString">display string</param>
        /// <param name="validateGesture">If true, throws an exception if the key and modifier are not valid</param>
        private KeyGesture(Key key, ModifierKeys modifiers, string displayString, bool validateGesture)
        {
            if(!ModifierKeysConverter.IsDefinedModifierKeys(modifiers))
                throw new InvalidEnumArgumentException("modifiers", (int)modifiers, typeof(ModifierKeys));

            if(!IsDefinedKey(key))
                throw new InvalidEnumArgumentException("key", (int)key, typeof(Key));

            ArgumentNullException.ThrowIfNull(displayString);

            if (validateGesture && !IsValid(key, modifiers))
            {
                throw new NotSupportedException(SR.Format(SR.KeyGesture_Invalid, modifiers, key));
            }

            _modifiers = modifiers;
            _key = key;
            _displayString = displayString;
        }
#endregion Constructors

        //------------------------------------------------------

View on GitHub (pinned to 81131a70a4)