{"record":{"id":"32c88e2deb2df63c","repo":"python/cpython","slug":"unrecognised-keyname-s-at-char-d-of-s","errorCode":null,"errorMessage":"unrecognised keyname `%s' at char %d of %s","messagePattern":"unrecognised keyname `(.+?)' at char (.+?) of (.+?)","errorType":"validation","errorClass":"KeySpecError","httpStatus":null,"severity":"error","filePath":"Lib/_pyrepl/keymap.py","lineNumber":169,"sourceCode":"                s += 3\n            elif c.isdigit():\n                n = key[s + 1 : s + 4]\n                ret = chr(int(n, 8))\n                s += 4\n            elif c == \"x\":\n                n = key[s + 2 : s + 4]\n                ret = chr(int(n, 16))\n                s += 4\n            elif c == \"<\":\n                t = key.find(\">\", s)\n                if t == -1:\n                    raise KeySpecError(\n                        \"unterminated \\\\< starting at char %d of %s\"\n                        % (s + 1, repr(key))\n                    )\n                ret = key[s + 2 : t].lower()\n                if ret not in _keynames:\n                    raise KeySpecError(\n                        \"unrecognised keyname `%s' at char %d of %s\"\n                        % (ret, s + 2, repr(key))\n                    )\n                ret = _keynames[ret]\n                s = t + 1\n            else:\n                raise KeySpecError(\n                    \"unknown backslash escape %s at char %d of %s\"\n                    % (repr(c), s + 2, repr(key))\n                )\n        else:\n            ret = key[s]\n            s += 1\n    if ctrl:\n        if len(ret) == 1:\n            ret = chr(ord(ret) & 0x1F)  # curses.ascii.ctrl()\n        elif ret in {\"left\", \"right\"}:\n            ret = f\"ctrl {ret}\"","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pyrepl/keymap.py#L151-L187","documentation":"KeySpecError from _parse_single_key_sequence in Lib/_pyrepl/keymap.py. Inside a \\<...> named-key reference, the enclosed name (lowercased by the parser) must exist in the module's _keynames table of recognized key names. An unknown name raises this error with the name and its position in the spec.","triggerScenarios":"Specs like \\<pageup> where the table only knows 'pgup', or invented names like \\<scroll-up>; the name is lowercased before lookup, so case errors alone do not trigger it, but aliases and abbreviations do.","commonSituations":"Assuming terminfo/curses key spellings (kf1 vs f1, pgup vs pageup) carry over to pyrepl; version skew where a key name exists in readline/other tools but not in _keynames; typos in config files.","solutions":["Open Lib/_pyrepl/keymap.py and read the _keynames dict; use exactly one of its names inside \\<...>.","Common correct names include up, down, left, right, home, end, pgup (not pageup), pgdn, f1..f12, delete, insert, escape, tab.","Validate specs at config load with _parse_single_key_sequence so bad names surface immediately with position info."],"exampleFix":"# before\nkeymap = {r'\\<pageup>': 'scroll-up'}\n\n# after\nkeymap = {r'\\<pgup>': 'scroll-up'}","handlingStrategy":"validation","validationCode":"from _pyrepl.keymap import _keynames\n\ndef known_keyname(spec):\n    import re\n    m = re.search(r'\\\\<([^>]*)>', spec)\n    return m is None or m.group(1).lower() in _keynames","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Source key names from _keynames in Lib/_pyrepl/keymap.py, not from readline docs.","Prefer pgup/pgdn spellings; verify f-key and special names before use.","Fail fast: validate the whole keymap once at startup."],"tags":["python","pyrepl","keymap","parsing","key-names"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}