{"record":{"id":"3c4d0a85417fcdb9","repo":"oobabooga/textgen","slug":"unknown-escape-at-src","errorCode":null,"errorMessage":"unknown escape at {src}","messagePattern":"unknown escape at (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"warning","filePath":"modules/grammar/grammar_utils.py","lineNumber":136,"sourceCode":"    if src[0] == \"\\\\\":\n        esc = src[1]\n        if esc == \"x\":\n            return read_hex(src[2:4]), src[4:]\n        elif esc == \"u\":\n            return read_hex(src[2:6]), src[6:]\n        elif esc == \"U\":\n            return read_hex(src[2:10]), src[10:]\n        elif esc in ('\"', \"[\", \"]\", \"\\\\\", \"-\"):\n            return esc, src[2:]\n        elif esc == \"r\":\n            return \"\\r\", src[2:]\n        elif esc == \"n\":\n            return \"\\n\", src[2:]\n        elif esc == \"t\":\n            return \"\\t\", src[2:]\n        elif esc == \"\\\\\":\n            return \"\\\\\", src[2:]\n        raise RuntimeError(\"unknown escape at \" + src)\n    elif src:\n        return src[0], src[1:]\n    raise RuntimeError(\"unexpected end of input\")\n\n\ndef parse_sequence(state, src, rule_name, outbuf, is_nested):\n    out_start_pos = len(outbuf)\n\n    # sequence size, will be replaced at end when known\n    outbuf.append(TO_BE_FILLED_MARKER)\n\n    last_sym_start = len(outbuf)\n    remaining_src = src\n    while remaining_src:\n        if remaining_src[0] == '\"':  # literal string\n            remaining_src = remaining_src[1:]\n            last_sym_start = len(outbuf)\n            while remaining_src[0] != '\"':","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/oobabooga/textgen/blob/ed888c71f221df552750e1834b3654abab8ae345/modules/grammar/grammar_utils.py#L118-L154","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nnum ::= \"\\d+\"\n\n// after\nnum ::= [0-9]+\n","handlingStrategy":"validation","validationCode":"import re\n\nSUPPORTED_ESCAPE = re.compile(r'\\\\(?:[\"\\[\\]\\\\\\-rnt]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})')\nUNSUPPORTED = re.compile(r'\\\\(?![\"\\[\\]\\\\\\-rntxuU])')\n\ndef no_regex_escapes(grammar: str) -> bool:\n    return not UNSUPPORTED.search(grammar)\n","typeGuard":null,"tryCatchPattern":"try:\n    parse_grammar(grammar_text)\nexcept RuntimeError as e:\n    if 'unknown escape' in str(e):\n        raise ValueError('Grammar uses a non-GBNF escape (regex-style \\\\d/\\\\w/\\\\s?); rewrite with character classes') from None\n    raise\n","preventionTips":["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."],"tags":["grammar","gbnf","syntax-error","escapes"],"backgroundTag":null,"analyzedSha":"ed888c71f221df552750e1834b3654abab8ae345","analyzedAt":"2026-08-15T05:24:21.000Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}