{"record":{"id":"96d65f87aab8eb5c","repo":"tui-cs/Terminal.Gui","slug":"propertyname-reader-getstring-is-not-a-v","errorCode":null,"errorMessage":"{propertyName}: \"{reader.GetString ()}\" is not a valid Key.","messagePattern":"(.+?): \"(.+?)\" is not a valid Key\\.","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"Terminal.Gui/Configuration/KeyCodeJsonConverter.cs","lineNumber":55,"sourceCode":"                    switch (propertyName!.ToLowerInvariant ())\n                    {\n                        case \"key\":\n                            if (reader.TokenType == JsonTokenType.String)\n                            {\n                                if (Enum.TryParse (reader.GetString (), false, out key))\n                                {\n                                    break;\n                                }\n\n                                // The enum uses \"D0..D9\" for the number keys\n                                if (Enum.TryParse (reader.GetString ()!.TrimStart ('D', 'd'), false, out key))\n                                {\n                                    break;\n                                }\n\n                                if (key == KeyCode.Null)\n                                {\n                                    throw new JsonException (\n                                                             $\"{propertyName}: \\\"{reader.GetString ()}\\\" is not a valid Key.\"\n                                                            );\n                                }\n                            }\n                            else if (reader.TokenType == JsonTokenType.Number)\n                            {\n                                try\n                                {\n                                    key = (KeyCode)reader.GetInt32 ();\n                                }\n                                catch (InvalidOperationException ioe)\n                                {\n                                    throw new JsonException ($\"{propertyName}: Error parsing Key value: {ioe.Message}\", ioe);\n                                }\n                                catch (FormatException ioe)\n                                {\n                                    throw new JsonException ($\"{propertyName}: Error parsing Key value: {ioe.Message}\", ioe);\n                                }","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/tui-cs/Terminal.Gui/blob/2e47b11478db083499917f2ad27c34d30efb0df1/Terminal.Gui/Configuration/KeyCodeJsonConverter.cs#L37-L73","documentation":"Thrown by KeyCodeJsonConverter.Read (KeyCodeJsonConverter.cs:53-58) when the \"Key\" property value is a string that neither Enum.TryParse(KeyCode) nor Enum.TryParse with a trimmed leading 'D'/'d' (for the D0..D9 digit-key enum names) can resolve, and the resulting key is still KeyCode.Null. The string is not a recognized KeyCode enum name.","triggerScenarios":"A keybinding JSON object has \"Key\": \"<bad>\" where <bad> is a typo or a non-enum name (e.g. \"Enter2\", \"CtrlA\", \"Return\" if not in the enum, \"Spacebar\" instead of \"Space\"). The converter tried exact enum parse and D-prefix-trimmed parse; both failed.","commonSituations":"User typos a key name in config. User writes a modifier-combined name in the Key field (\"Ctrl+A\") instead of using the Modifiers array. User uses a Windows virtual-key name not present in the KeyCode enum. Case sensitivity: the first Enum.TryParse uses caseSensitive=true, so \"enter\" (lowercase) fails this path — though the D-trim path is also case-sensitive.","solutions":["Use the exact KeyCode enum member name (case-sensitive): \"Enter\", \"Home\", \"Space\", \"D0\", \"F1\", etc. Check the KeyCode enum definition for valid names.","For digit keys use \"D0\" through \"D9\" (the converter also accepts \"0\"..\"9\" by trimming the D prefix).","Put modifiers in the separate \"Modifiers\" array, not in the \"Key\" string.","For combined keys prefer the Key[] string format (\"Ctrl+A\") which uses Key.TryParse and is more lenient.","If case-insensitivity is needed, use the Key[] array form rather than the object KeyCode form."],"exampleFix":"// before\n{ \"Key\": \"enter\", \"Modifiers\": [\"Ctrl\"] }\n\n// after\n{ \"Key\": \"Enter\", \"Modifiers\": [\"Ctrl\"] }","handlingStrategy":"validation","validationCode":"using Terminal.Gui.Input;\n\nstatic bool IsValidKeyCodeName (string? name)\n{\n    if (string.IsNullOrEmpty (name)) return false;\n    if (Enum.TryParse<KeyCode> (name, false, out _)) return true;\n    // the D0..D9 trim path\n    if (Enum.TryParse<KeyCode> (name!.TrimStart ('D', 'd'), false, out _)) return true;\n    return false;\n}\n\nif (!IsValidKeyCodeName (keyName))\n{\n    // correct the name before writing config\n}","typeGuard":"static bool IsValidKeyCodeName (string? name)\n    => !string.IsNullOrEmpty (name)\n       && (Enum.TryParse<KeyCode> (name, false, out _)\n           || Enum.TryParse<KeyCode> (name!.TrimStart ('D', 'd'), false, out _));","tryCatchPattern":"try\n{\n    ConfigurationManager.Load (configJson);\n}\ncatch (JsonException ex) when (ex.Message.Contains (\"is not a valid Key\"))\n{\n    // The \"Key\" string does not match a KeyCode enum name.\n    // Replace it with the correct case-sensitive KeyCode name and reload.\n}","preventionTips":["Use the exact, case-sensitive KeyCode enum member name (Enter, Home, Space, D0, F1).","Put modifiers in the Modifiers array, not in the Key string.","Prefer the Key[] string-array format for keybindings — it is more lenient.","Keep a reference to the KeyCode enum definition when authoring keybindings."],"tags":["json","configuration","keybindings","key","enum","serialization"],"backgroundTag":null,"analyzedSha":"2e47b11478db083499917f2ad27c34d30efb0df1","analyzedAt":"2026-08-13T19:20:08.826Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}