oracle/graal · error · UnsupportedRegexException
too many sequences in a single group
Error message
too many sequences in a single group
What it means
Thrown by Group.checkMaxSize when the number of alternatives (sequences) in a single group exceeds TRegexOptions.TRegexParserTreeMaxNumberOfSequencesInGroup (Short.MAX_VALUE = 32767). The AST stores alternatives in a list bounded so sequence indices stay short-representable; oversized alternations are rejected during parsing.
Source
Thrown at regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/parser/ast/Group.java:375
sequence.setParent(this);
alternatives.add(sequence);
checkMaxSize();
}
/**
* Inserts a new alternative to this group. The new alternative will be <em>inserted at the
* beginning</em>, meaning it will have the <em>highest priority</em> among all the
* alternatives.
*/
public void insertFirst(Sequence sequence) {
sequence.setParent(this);
alternatives.add(0, sequence);
checkMaxSize();
}
private void checkMaxSize() {
if (alternatives.size() > TRegexOptions.TRegexParserTreeMaxNumberOfSequencesInGroup) {
throw new UnsupportedRegexException("too many sequences in a single group");
}
}
/**
* Creates a new empty alternatives and adds it to the end of the list of alternatives.
*
* @param ast The AST that the new alternative should belong to
* @return The newly created alternative
*/
public Sequence addSequence(RegexAST ast) {
Sequence sequence = ast.createSequence();
add(sequence);
return sequence;
}
public Sequence getLastAlternative() {
return alternatives.get(size() - 1);
}View on GitHub (pinned to a66e9ccd1d)
Solutions
- Split the alternation into several regexes each below the cap and match them in a loop.
- Use a different data structure for keyword matching (Aho-Corasick automaton, a trie, or a HashSet of literals) instead of a giant regex.
- Factor common prefixes/suffixes of the alternatives to shrink the branch count.
- Warn in your generator when the branch count approaches 32767.
Example fix
// before
String pattern = words.stream().map(Pattern::quote).collect(Collectors.joining("|", "^(?:", ")$")); // one group
boolean m = Pattern.compile(pattern).matcher(s).matches();
// after
Set<String> set = Set.copyOf(words); // literal lookup, no regex
boolean m = set.contains(s); // or chunk into several patterns of <=10000 branches each Defensive patterns
Strategy: validation
Validate before calling
int branches = pattern.split("\\|", -1).length - 1; if (branches > 32_000) throw new IllegalArgumentException("too many sequences in one group (max 32767)"); Type guard
null
Try / catch
try { compile(pattern); } catch (UnsupportedRegexException e) { if (e.getMessage().contains("too many sequences")) { /* split alternation into multiple patterns */ } } Prevention
- Never join unbounded word lists into one alternation.
- Chunk generated alternations into patterns of a few thousand branches.
- Prefer set/trie lookups for pure keyword matching.
When it happens
Trigger: Compiling a single alternation group with more than 32767 branches, e.g. (word1|word2|...|word40000), typically from joining a large word list into one pattern.
Common situations: Dictionary/keyword matching built by String.join("|", words); blocklist/allowlist regexes generated from databases; incremental growth of a word list crossing the threshold after a data update.
Related errors
- Class set expression maximum nesting level exceeded
- too many terms in a single sequence
- too many capture groups
- DFA transition size explosion
- ASTSuccessor explosion
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/3d4a1e3c32018fd6.
Report an issue: GitHub.