babalae/better-genshin-impact · error · ArgumentOutOfRangeException

未指定按键,无法转换为VK。

Error message

未指定按键,无法转换为VK。

What it means

KeyBindingsConfig.ToVK converts a KeyId (the app's input enum) to a Windows virtual-key code (VK). KeyId.None means no key was assigned, and KeyId.None has no corresponding VK code, so the conversion is meaningless and throws ArgumentOutOfRangeException. The remaining KeyId values share the same numeric values as VK, so they cast directly.

Source

Thrown at BetterGenshinImpact/Core/Config/KeyBindingsConfig.cs:433

            KeyId.Subtract => "Num -",
            KeyId.Add => "Num +",
            KeyId.NumEnter => "Num Enter",
            // 默认使用枚举名
            _ => value.ToString(),
        };
    }

    /// <summary>
    /// 将KeyId转换为VK
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static VK ToVK(this KeyId value)
    {
        return value switch
        {
            // 这两个值在VK中没有,抛异常
            KeyId.None => throw new ArgumentOutOfRangeException(nameof(value), "未指定按键,无法转换为VK。"),
            KeyId.Unknown => throw new ArgumentOutOfRangeException(nameof(value), "未知按键,无法转换为VK。"),
            // 剩下的值相同,直接转
            _ => (VK)value,
        };
    }

    /// <summary>
    /// 将KeyId转换为System.Windows.Input.Key
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static Key ToInputKey(this KeyId value)
    {
        // 部分按键名称相同,使用名称转换
        try
        {
            return Enum.Parse<Key>(value.ToString());
        }

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Check for KeyId.None before calling ToVK and skip/handle the unassigned case.
  2. Ensure config initialization assigns a real key to every binding used.
  3. Use ToInputKey for keyboard keys when a System.Windows.Input.Key is what you need.

Example fix

// before
var vk = binding.KeyId.ToVK();

// after
if (binding.KeyId == KeyId.None) return;
var vk = binding.KeyId.ToVK();
Defensive patterns

Strategy: validation

Validate before calling

if (binding.KeyId == KeyId.None) return; // or throw a clearer config error
var vk = binding.KeyId.ToVK();

Type guard

static bool IsAssignedKey(KeyId k) => k != KeyId.None && k != KeyId.Unknown;

Try / catch

try { vk = keyId.ToVK(); }
catch (ArgumentOutOfRangeException) { /* key unassigned, skip */ }

Prevention

When it happens

Trigger: Calling someKeyId.ToVK() when the KeyId was never set (still KeyId.None); deserialized key-binding config where a binding was left unset; hotkey features invoking ToVK on a placeholder value.

Common situations: Default config with unassigned hotkeys; scripts reading a binding before the user configured it; newly added KeyId values that default to None.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/ff015606c23c83d9. Report an issue: GitHub.