{"record":{"id":"9fab163ce933ae39","repo":"oracle/graal","slug":"literal-escape-not-supported-in-this-context","errorCode":null,"errorMessage":"Literal escape not supported in this context","messagePattern":"Literal escape not supported in this context","errorType":"exception","errorClass":"UnsupportedRegexException","httpStatus":null,"severity":"error","filePath":"regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/flavor/java/JavaRegexLexer.java","lineNumber":880,"sourceCode":"                    int i = position;\n                    if (!findChars('}')) {\n                        throw syntaxError(JavaErrorMessages.UNCLOSED_CHAR_NAME, ErrorCode.InvalidEscape);\n                    }\n                    advance(); // skip '}'\n                    String name = pattern.substring(i, position - 1);\n                    try {\n                        return Character.codePointOf(name);\n                    } catch (IllegalArgumentException x) {\n                        throw syntaxError(JavaErrorMessages.unknownCharacterName(name), ErrorCode.InvalidEscape);\n                    }\n                }\n                throw syntaxError(JavaErrorMessages.ILLEGAL_CHARACTER_NAME, ErrorCode.InvalidEscape);\n            case 'a':\n                return 0x7;\n            case 'e':\n                return 0x1b;\n            case 'Q':\n                throw new UnsupportedRegexException(\"Literal escape not supported in this context\");\n            default:\n                return -1;\n        }\n    }\n\n    private int parseUnicodeHexEscape() {\n        if (consumingLookahead(RegexLexer::isHexDigit, 4)) {\n            return Integer.parseInt(pattern, position - 4, position, 16);\n        }\n        throw syntaxError(JavaErrorMessages.ILLEGAL_UNICODE_ESC_SEQ, ErrorCode.InvalidEscape);\n    }\n\n    @Override\n    protected int parseCustomEscapeCharFallback(int c, boolean inCharClass) {\n        // any non-alphabetic character can be used after an escape\n        // digits are not accepted here since they should have been parsed as octal sequence or\n        // backreference earlier\n        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {","sourceCodeStart":862,"sourceCodeEnd":898,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/flavor/java/JavaRegexLexer.java#L862-L898","documentation":"Thrown when the \\Q...\\E quoting escape appears in a context where the Java-flavor lexer resolves single-character escapes (parseCustomCharEscape), most notably inside a character class. Outside classes \\Q is handled as a multi-char construct in parseCustomEscape, but inside [...] the lexer reaches case 'Q' of the single-char escape parser and rejects it, because quoted literal strings cannot be represented as a charset range there.","triggerScenarios":"Compiling a Java-flavor pattern with \\Q...\\E inside a character class, e.g. \"[\\\\Qa-b\\\\E]\" or \"[\\\\Q.*+?\\\\E]\". While lexing the class contents, parseCustomEscape dispatches to the char-escape path, case 'Q' throws UnsupportedRegexException('Literal escape not supported in this context').","commonSituations":"Patterns that quote a user-supplied literal into a character class to 'safely' include metacharacters; code generated from templates that wraps arbitrary strings in \\Q...\\E regardless of whether the insertion point is inside [...]; java.util.regex accepts [\\Q...\\E], so the same pattern works on the JDK but fails on TRegex.","solutions":["Escape each character individually with Pattern.quote-style logic or a per-char backslash escape instead of \\Q...\\E inside the class","Move the quoted literal out of the character class: match it as an alternation branch (?:\\\\Qliteral\\\\E) rather than inside [...]","Pre-compute the escaped class contents (e.g. escape '-', ']', '^', '\\\\') when building the pattern string dynamically"],"exampleFix":"// before\nString p = \"[\\\\Qa-b*c\\\\E]\";\n\n// after\nString p = \"[a\\\\-b*c]\"; // escape metacharacters individually","handlingStrategy":"validation","validationCode":"boolean hasQInCharClass(String pattern) {\n    return java.util.regex.Pattern.compile(\"\\\\[[^\\\\]]*\\\\\\\\Q\").matcher(pattern).find();\n}","typeGuard":null,"tryCatchPattern":"try {\n    RegexObject re = compileJavaFlavor(pattern);\n} catch (UnsupportedRegexException e) {\n    // \\Q...\\E in a character class: escape members individually and recompile\n}","preventionTips":["Escape class members individually (-, ], ^, backslash) instead of \\Q...\\E inside [...] ","When injecting user literals into patterns, use per-character escaping, not \\Q quoting, if the literal may land inside a class"],"tags":["regex","java-flavor","escape-sequence","character-class","unsupported-feature"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}