python/cpython · error · KeySpecError
\M must be followed by `-' (char %d of %s)
Error message
\M must be followed by `-' (char %d of %s)
What it means
KeySpecError from _parse_single_key_sequence in Lib/_pyrepl/keymap.py. The Meta/Alt modifier escape \m must be written \M- with a literal dash; any other character after \m raises this error, mirroring the \C- rule for Ctrl. The message includes the 1-based character position in the spec.
Source
Thrown at Lib/_pyrepl/keymap.py:142
c = key[s + 1].lower()
if c in _escapes:
ret = _escapes[c]
s += 2
elif c == "c":
if key[s + 2] != "-":
raise KeySpecError(
"\\C must be followed by `-' (char %d of %s)"
% (s + 2, repr(key))
)
if ctrl:
raise KeySpecError(
"doubled \\C- (char %d of %s)" % (s + 1, repr(key))
)
ctrl = 1
s += 3
elif c == "m":
if key[s + 2] != "-":
raise KeySpecError(
"\\M must be followed by `-' (char %d of %s)"
% (s + 2, repr(key))
)
if meta:
raise KeySpecError(
"doubled \\M- (char %d of %s)" % (s + 1, repr(key))
)
meta = 1
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 == "<":View on GitHub (pinned to bc6749cc3b)
Solutions
- Use the canonical form \M-x with the dash.
- Prefer composing Meta as an actual ESC prefix only if the parser supports it in your version; otherwise stick to \M-.
- Run custom specs through _parse_single_key_sequence during config load to fail fast.
Example fix
# before
keymap = {r'\mx': 'next-history'}
# after
keymap = {r'\M-x': 'next-history'} Defensive patterns
Strategy: validation
Validate before calling
import re
def valid_meta(spec):
# every \m / \M must be followed by '-'
return not re.search(r'\\[mM](?!-)', spec) Prevention
- Write \M-x with the dash, never \mx.
- Do not transliterate Emacs 'M-x' notation literally.
- Test-parse custom keymaps at startup.
When it happens
Trigger: Key specs where \m is not followed by '-', such as "\\Ma" or "\\meta-x"; the escape letter is lowercased so both \M and \m are checked.
Common situations: Users accustomed to Emacs 'M-x' or readline '\M-x' shorthand writing \mx; converting terminal escape tables where ESC-prefixed keys are described as \M<key> without the dash; typos in custom pyrepl keymaps.
Related errors
- \C must be followed by `-' (char %d of %s)
- doubled \C- (char %d of %s)
- doubled \M- (char %d of %s)
- unterminated \< starting at char %d of %s
- unrecognised keyname `%s' at char %d of %s
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/c8e805e19f4b79ba.
Report an issue: GitHub.