oobabooga/textgen · warning · RuntimeError
unknown escape at {src}
Error message
unknown escape at {src} What it means
Raised by parse_char (modules/grammar/grammar_utils.py:136): inside a quoted literal, a backslash escape is followed by a letter the GBNF parser does not recognize. Supported escapes are \" \[ \] \\ \- \r \n \t \xHH \uHHHH \UHHHHHHHH; anything else (\d, \w, \s, \', \0) hits the RuntimeError.
Source
Thrown at modules/grammar/grammar_utils.py:136
if src[0] == "\\":
esc = src[1]
if esc == "x":
return read_hex(src[2:4]), src[4:]
elif esc == "u":
return read_hex(src[2:6]), src[6:]
elif esc == "U":
return read_hex(src[2:10]), src[10:]
elif esc in ('"', "[", "]", "\\", "-"):
return esc, src[2:]
elif esc == "r":
return "\r", src[2:]
elif esc == "n":
return "\n", src[2:]
elif esc == "t":
return "\t", src[2:]
elif esc == "\\":
return "\\", src[2:]
raise RuntimeError("unknown escape at " + src)
elif src:
return src[0], src[1:]
raise RuntimeError("unexpected end of input")
def parse_sequence(state, src, rule_name, outbuf, is_nested):
out_start_pos = len(outbuf)
# sequence size, will be replaced at end when known
outbuf.append(TO_BE_FILLED_MARKER)
last_sym_start = len(outbuf)
remaining_src = src
while remaining_src:
if remaining_src[0] == '"': # literal string
remaining_src = remaining_src[1:]
last_sym_start = len(outbuf)
while remaining_src[0] != '"':View on GitHub (pinned to ed888c71f2)
Solutions
- Replace regex escapes with GBNF constructs: \d -> [0-9], \w -> [a-zA-Z0-9_], \s -> [ \t\r\n].
- For quotes/brackets inside literals use the supported list: \", \[, \], \\, \- or hex \xHH for anything else.
- After editing, run the grammar through the parser once before attaching it to a generation request.
Example fix
// before num ::= "\d+" // after num ::= [0-9]+
Defensive patterns
Strategy: validation
Validate before calling
import re
SUPPORTED_ESCAPE = re.compile(r'\\(?:["\[\]\\\-rnt]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})')
UNSUPPORTED = re.compile(r'\\(?!["\[\]\\\-rntxuU])')
def no_regex_escapes(grammar: str) -> bool:
return not UNSUPPORTED.search(grammar)
Try / catch
try:
parse_grammar(grammar_text)
except RuntimeError as e:
if 'unknown escape' in str(e):
raise ValueError('Grammar uses a non-GBNF escape (regex-style \\d/\\w/\\s?); rewrite with character classes') from None
raise
Prevention
- Remember GBNF is not regex: \d, \w, \s do not exist.
- Keep a translation table (regex escape -> char class) next to your grammar tooling.
- Encode arbitrary chars as \xHH instead of inventing escapes.
When it happens
Trigger: A grammar literal using regex-style escapes, e.g. root ::= "a\d+" or "\wword"; escaping a quote with \' instead of \"; using \0 for NUL instead of \x00.
Common situations: Porting a regex to GBNF and keeping regex escapes verbatim; JSON-sourced grammars where double-escaping got mangled; assumption that PCRE escapes work in GBNF.
Related errors
- expecting name at {src}
- unexpected end of input
- expecting ')' at {remaining_src}
- expecting ::= at {remaining_src}
- unknown hex char {c}
AI-assisted analysis of oobabooga/textgen@ed888c71f2 (2026-08-15).
Data as JSON: /api/errors/3c4d0a85417fcdb9.
Report an issue: GitHub.