dotnet/wpf · error · InvalidEnumArgumentException

InvalidEnumArgumentException("actions", (int)actions…

Error message

InvalidEnumArgumentException("actions", (int)actions, typeof(RawKeyboardActions))

What it means

The RawKeyboardInputReport constructor validates the actions parameter with IsValidRawKeyboardActions and throws InvalidEnumArgumentException when the value is not a defined member of RawKeyboardActions. RawKeyboardActions flags (ReportUp/ReportDown/ReportMultipleActions...) must describe a coherent keyboard report; arbitrary integer values are rejected.

Solutions

  1. Use only named RawKeyboardActions values (ReportUp, ReportDown, ReportMultipleActions) instead of casting ints.
  2. Validate the value with Enum.IsDefined(typeof(RawKeyboardActions), actions) before constructing the report.
  3. Map platform-specific constants to the WPF enum explicitly in your interop layer.
  4. Re-derive actions from the message (WM_KEYUP vs WM_KEYDOWN) rather than passing raw flag data.

Example fix

// before
var report = new RawKeyboardInputReport(inputSource, mode, timestamp,
    (RawKeyboardActions)rawInt, scanCode, ext, sys, vk, extraInfo); // may throw

// after
var actions = (RawKeyboardActions)rawInt;
if (!IsValidRawKeyboardActions(actions))
    actions = up ? RawKeyboardActions.ReportUp : RawKeyboardActions.ReportDown;
var report = new RawKeyboardInputReport(inputSource, mode, timestamp,
    actions, scanCode, ext, sys, vk, extraInfo);
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidRawKeyboardActionsValue(RawKeyboardActions a) =>
    Enum.IsDefined(typeof(RawKeyboardActions), a) ||
    a == (RawKeyboardActions.ReportUp | RawKeyboardActions.ReportMultipleActions);

Type guard

bool TryGetKeyboardActions(int raw, out RawKeyboardActions actions)
{
    actions = (RawKeyboardActions)raw;
    return Enum.IsDefined(typeof(RawKeyboardActions), actions);
}

Try / catch

try
{
    var report = new RawKeyboardInputReport(src, mode, ts, actions, scan, ext, sys, vk, extra);
}
catch (InvalidEnumArgumentException ex)
{
    Log($"Invalid RawKeyboardActions: {ex}");
}

Prevention

When it happens

Trigger: Constructing RawKeyboardInputReport with an out-of-range or undefined RawKeyboardActions value, e.g. casting a raw int from platform data, combining flags into an invalid combination, or passing 0/undefined bits.

Common situations: Interop/P-Invoke code building keyboard input reports from Win32 messages where the raw integer was not mapped to the enum; tests synthesizing input with hand-picked flag values; version drift after the enum gains or loses members.

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/8da481c8c06996d9. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/RawKeyboardInputReport.cs:59

        /// <param name="virtualKey">
        ///     The Win32 virtual key code if a key is being reported.
        /// </param>
        /// <param name="extraInformation">
        ///     Any extra information being provided along with the input.
        /// </param>
        public RawKeyboardInputReport(
            PresentationSource inputSource,
            InputMode mode,
            int timestamp, 
            RawKeyboardActions actions, 
            int scanCode, 
            bool isExtendedKey,
            bool isSystemKey,
            int virtualKey, 
            IntPtr extraInformation) : base(inputSource, InputType.Keyboard, mode, timestamp)
        {
            if (!IsValidRawKeyboardActions(actions))
                throw new System.ComponentModel.InvalidEnumArgumentException("actions", (int)actions, typeof(RawKeyboardActions));

            _actions = actions;
            _scanCode = scanCode;
            _isExtendedKey = isExtendedKey;
            _isSystemKey = isSystemKey;
            _virtualKey = virtualKey;
            _extraInformation = extraInformation;
        }

        /// <summary>
        ///     Read-only access to the set of actions that were reported.
        /// </summary>
        public RawKeyboardActions Actions {get {return _actions;}}

        /// <summary>
        ///     Read-only access to the scan code that was reported.
        /// </summary>
        public int ScanCode {get {return _scanCode;}}

View on GitHub (pinned to 81131a70a4)