oracle/graal · error · UnsupportedRegexException

too many terms in a single sequence

Error message

too many terms in a single sequence

What it means

Thrown by Term.setSeqIndex when a sequence's term index reaches TRegexOptions.TRegexParserTreeMaxNumberOfTermsInSequence (Short.MAX_VALUE = 32767). Sequence positions are stored in a short, so a single regex sequence with 32768+ terms cannot be represented and parsing is rejected.

Source

Thrown at regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/parser/ast/Term.java:80

    Term(Term copy) {
        super(copy);
    }

    @Override
    public abstract Term copy(RegexAST ast);

    @Override
    public abstract Term copyRecursive(RegexAST ast, CompilationBuffer compilationBuffer);

    public int getSeqIndex() {
        return seqIndex;
    }

    public void setSeqIndex(int seqIndex) {
        this.seqIndex = seqIndex;
        if (seqIndex >= TRegexOptions.TRegexParserTreeMaxNumberOfTermsInSequence) {
            throw new UnsupportedRegexException("too many terms in a single sequence");
        }
    }

    @Override
    public RegexASTSubtreeRootNode getSubTreeParent() {
        RegexASTNode current = this;
        while (current.getParent() != null) {
            assert current instanceof Term;
            if (current.getParent() instanceof RegexASTSubtreeRootNode) {
                return (RegexASTSubtreeRootNode) current.getParent();
            }
            // structure is always Group -> Sequence -> Term
            current = current.getParent().getParent();
        }
        // this should only be reached by nodes generated by RegexAST#createNFAInitialStates()!
        return null;
    }

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Take the long literal out of the regex and compare with String.contains/equals in application code.
  2. Group repeated elements into quantifiers (a{5} instead of aaaaa) or character classes.
  3. Split the pattern into several regexes and combine the results.

Example fix

// before
String pattern = "^" + hugeLiteral + "$"; // hugeLiteral > 32767 chars

// after
boolean m = input.equals(hugeLiteral); // plain string compare, no regex needed
Defensive patterns

Strategy: validation

Validate before calling

if (pattern.length() > 32_000) throw new IllegalArgumentException("pattern too long: single sequence limited to 32767 terms");

Type guard

null

Try / catch

try { compile(pattern); } catch (UnsupportedRegexException e) { if (e.getMessage().contains("too many terms")) { /* shorten or split the pattern */ } }

Prevention

When it happens

Trigger: Compiling one flat sequence with more than 32767 consecutive terms, e.g. a very long literal string (every character is a term) or a generated concatenation without alternation.

Common situations: Embedding a large literal (a whole token, hash list, or text blob) into a pattern; patterns generated from data that concatenate thousands of quoted literals; regexes built by string concatenation in a loop that grows unbounded over releases.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/33394decc7fbe9da. Report an issue: GitHub.