oracle/graal · error · UnsupportedRegexException
Literal escape not supported in this context
Error message
Literal escape not supported in this context
What it means
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.
Source
Thrown at regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/flavor/java/JavaRegexLexer.java:880
int i = position;
if (!findChars('}')) {
throw syntaxError(JavaErrorMessages.UNCLOSED_CHAR_NAME, ErrorCode.InvalidEscape);
}
advance(); // skip '}'
String name = pattern.substring(i, position - 1);
try {
return Character.codePointOf(name);
} catch (IllegalArgumentException x) {
throw syntaxError(JavaErrorMessages.unknownCharacterName(name), ErrorCode.InvalidEscape);
}
}
throw syntaxError(JavaErrorMessages.ILLEGAL_CHARACTER_NAME, ErrorCode.InvalidEscape);
case 'a':
return 0x7;
case 'e':
return 0x1b;
case 'Q':
throw new UnsupportedRegexException("Literal escape not supported in this context");
default:
return -1;
}
}
private int parseUnicodeHexEscape() {
if (consumingLookahead(RegexLexer::isHexDigit, 4)) {
return Integer.parseInt(pattern, position - 4, position, 16);
}
throw syntaxError(JavaErrorMessages.ILLEGAL_UNICODE_ESC_SEQ, ErrorCode.InvalidEscape);
}
@Override
protected int parseCustomEscapeCharFallback(int c, boolean inCharClass) {
// any non-alphabetic character can be used after an escape
// digits are not accepted here since they should have been parsed as octal sequence or
// backreference earlier
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {View on GitHub (pinned to a66e9ccd1d)
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
Example fix
// before String p = "[\\Qa-b*c\\E]"; // after String p = "[a\\-b*c]"; // escape metacharacters individually
Defensive patterns
Strategy: validation
Validate before calling
boolean hasQInCharClass(String pattern) {
return java.util.regex.Pattern.compile("\\[[^\\]]*\\\\Q").matcher(pattern).find();
} Try / catch
try {
RegexObject re = compileJavaFlavor(pattern);
} catch (UnsupportedRegexException e) {
// \Q...\E in a character class: escape members individually and recompile
} Prevention
- 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
When it happens
Trigger: 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').
Common situations: 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.
Related errors
- Extended grapheme cluster boundaries are not supported
- Grapheme clusters are not supported
- End of previous match boundary matcher is not supported
- Independent non-capturing groups are not supported
- possessive quantifiers are not supported
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/9fab163ce933ae39.
Report an issue: GitHub.