{"record":{"id":"0f9eff8016a70be9","repo":"dotnet/wpf","slug":"sr-format-sr-cannotconvertstringtotype-keytoken-tostring","errorCode":null,"errorMessage":"SR.Format(SR.CannotConvertStringToType, keyToken.ToString(), typeof(Key))","messagePattern":"SR\\.Format\\(SR\\.CannotConvertStringToType, keyToken\\.ToString\\(\\), typeof\\(Key\\)\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Input/KeyConverter.cs","lineNumber":123,"sourceCode":"            // If the token is empty, we presume \"None\" as our value but it is a success\n            if (keyToken.IsEmpty)\n                return Key.None;\n\n            // In case we're dealing with a lowercase character, we uppercase it\n            char firstChar = keyToken[0];\n            if (firstChar >= 'a' && firstChar <= 'z')\n                firstChar ^= (char)0x20;\n\n            // If this is a single-character we're dealing with, match digits/letters\n            if (keyToken.Length == 1 && char.IsLetterOrDigit(firstChar))\n            {\n                // Match an ASCII digit or an ASCII letter (lower/uppercase)\n                if (char.IsAsciiDigit(firstChar)) // 0 - 9\n                    return Key.D0 + firstChar - '0';\n                else if (char.IsAsciiLetterUpper(firstChar)) // A - Z\n                    return Key.A + firstChar - 'A';\n                else\n                    throw new ArgumentException(SR.Format(SR.CannotConvertStringToType, keyToken.ToString(), typeof(Key)));\n            }\n\n            // It is a special key or an invalid one, we're gonna find out\n            switch (keyToken.Length)\n            {\n                case 2:\n                    // Special path for F1-F9 (switch would take 600 B in code size for no benefit)\n                    char secondChar = keyToken[1];\n                    if (firstChar == 'F' && (secondChar > '0' && secondChar <= '9'))\n                        return Key.F1 + secondChar - '1';\n                    // We've got one more special case for Key.Back/Backspace -> \"BS\"\n                    if (firstChar == 'B' && (secondChar is 'S' or 's'))\n                        return Key.Back;\n                    break;\n                case 3:\n                    switch (firstChar)\n                    {\n                        case 'A':","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Input/KeyConverter.cs#L105-L141","documentation":"KeyConverter.GetKeyFromString converts a string like 'A' or '5' to a Key. Single characters are mapped to Key.A/Key.D0 ranges only for ASCII letters and digits; any other single-character token (e.g. ',' or '€') that is not handled falls through and throws ArgumentException with CannotConvertStringToType including the token and typeof(Key).","triggerScenarios":"Calling KeyConverter.ConvertFrom (or ConvertFromInvariantString) with a one-character string that is not an ASCII digit or A–Z letter and is not a named key (e.g. ',', ';', or a non-ASCII character) — within the switch paths where keyToken.Length==1.","commonSituations":"Parsing keyboard shortcuts from config/XAML with wrong separators (e.g. 'Ctrl+,' semantics assumed), localized key names, or typos like 'Ctrl+Å' that don't map to a Key enum member.","solutions":["Use valid Key names (enum names like 'Enter', 'D1', 'OemComma') or ASCII letters/digits","Verify the shortcut string with a lookup before conversion (KeyConverter.IsValid or Enum.TryParse<Key>)","Fix the config/XAML value to use the documented key token format","Pre-parse with the supported separator '+' and validate each token"],"exampleFix":"// before\nvar key = (Key)new KeyConverter().ConvertFromString(\",\"); // throws\n// after\nstring token = \",\";\nKey key;\nif (!Enum.TryParse(token, ignoreCase: true, out key))\n    key = Key.OemComma; // or reject input","handlingStrategy":"validation","validationCode":"bool ok = token.Length == 1 ? char.IsAsciiLetterOrDigit(token[0]) : Enum.TryParse<Key>(token, ignoreCase: true, out _);\nif (!ok) throw new FormatException($\"'{token}' is not a valid Key\");","typeGuard":"static bool IsValidKeyToken(string s) => s.Length == 1 ? char.IsAsciiLetterOrDigit(s[0]) : Enum.TryParse<Key>(s, ignoreCase: true, out _);","tryCatchPattern":"try { var key = (Key)new KeyConverter().ConvertFromString(token); }\ncatch (ArgumentException ex) { log.Error($\"Cannot convert '{token}' to Key: {ex.Message}\"); }","preventionTips":["Validate shortcut strings before calling the converter","Use enum Key names for non-alphanumeric keys (e.g. OemComma, Enter)","Restrict user/config input to ASCII letters, digits, and known Key names"],"tags":["wpf","type-converter","keyboard","parsing"],"backgroundTag":"invalid-argument-format","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}