python/cpython · error · KeySpecError
unrecognised keyname `%s' at char %d of %s
Error message
unrecognised keyname `%s' at char %d of %s
What it means
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.
Source
Thrown at Lib/_pyrepl/keymap.py:169
s += 3
elif c.isdigit():
n = key[s + 1 : s + 4]
ret = chr(int(n, 8))
s += 4
elif c == "x":
n = key[s + 2 : s + 4]
ret = chr(int(n, 16))
s += 4
elif c == "<":
t = key.find(">", s)
if t == -1:
raise KeySpecError(
"unterminated \\< starting at char %d of %s"
% (s + 1, repr(key))
)
ret = key[s + 2 : t].lower()
if ret not in _keynames:
raise KeySpecError(
"unrecognised keyname `%s' at char %d of %s"
% (ret, s + 2, repr(key))
)
ret = _keynames[ret]
s = t + 1
else:
raise KeySpecError(
"unknown backslash escape %s at char %d of %s"
% (repr(c), s + 2, repr(key))
)
else:
ret = key[s]
s += 1
if ctrl:
if len(ret) == 1:
ret = chr(ord(ret) & 0x1F) # curses.ascii.ctrl()
elif ret in {"left", "right"}:
ret = f"ctrl {ret}"View on GitHub (pinned to bc6749cc3b)
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.
Example fix
# before
keymap = {r'\<pageup>': 'scroll-up'}
# after
keymap = {r'\<pgup>': 'scroll-up'} Defensive patterns
Strategy: validation
Validate before calling
from _pyrepl.keymap import _keynames
def known_keyname(spec):
import re
m = re.search(r'\\<([^>]*)>', spec)
return m is None or m.group(1).lower() in _keynames Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- \C must be followed by `-' (char %d of %s)
- doubled \C- (char %d of %s)
- \M must be followed by `-' (char %d of %s)
- doubled \M- (char %d of %s)
- unterminated \< starting at char %d of %s
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/32c88e2deb2df63c.
Report an issue: GitHub.