{"record":{"id":"3d4a1e3c32018fd6","repo":"oracle/graal","slug":"too-many-sequences-in-a-single-group","errorCode":null,"errorMessage":"too many sequences in a single group","messagePattern":"too many sequences in a single group","errorType":"exception","errorClass":"UnsupportedRegexException","httpStatus":null,"severity":"error","filePath":"regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/parser/ast/Group.java","lineNumber":375,"sourceCode":"        sequence.setParent(this);\n        alternatives.add(sequence);\n        checkMaxSize();\n    }\n\n    /**\n     * Inserts a new alternative to this group. The new alternative will be <em>inserted at the\n     * beginning</em>, meaning it will have the <em>highest priority</em> among all the\n     * alternatives.\n     */\n    public void insertFirst(Sequence sequence) {\n        sequence.setParent(this);\n        alternatives.add(0, sequence);\n        checkMaxSize();\n    }\n\n    private void checkMaxSize() {\n        if (alternatives.size() > TRegexOptions.TRegexParserTreeMaxNumberOfSequencesInGroup) {\n            throw new UnsupportedRegexException(\"too many sequences in a single group\");\n        }\n    }\n\n    /**\n     * Creates a new empty alternatives and adds it to the end of the list of alternatives.\n     *\n     * @param ast The AST that the new alternative should belong to\n     * @return The newly created alternative\n     */\n    public Sequence addSequence(RegexAST ast) {\n        Sequence sequence = ast.createSequence();\n        add(sequence);\n        return sequence;\n    }\n\n    public Sequence getLastAlternative() {\n        return alternatives.get(size() - 1);\n    }","sourceCodeStart":357,"sourceCodeEnd":393,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/parser/ast/Group.java#L357-L393","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nString pattern = words.stream().map(Pattern::quote).collect(Collectors.joining(\"|\", \"^(?:\", \")$\")); // one group\nboolean m = Pattern.compile(pattern).matcher(s).matches();\n\n// after\nSet<String> set = Set.copyOf(words); // literal lookup, no regex\nboolean m = set.contains(s); // or chunk into several patterns of <=10000 branches each","handlingStrategy":"validation","validationCode":"int branches = pattern.split(\"\\\\|\", -1).length - 1; if (branches > 32_000) throw new IllegalArgumentException(\"too many sequences in one group (max 32767)\");","typeGuard":"null","tryCatchPattern":"try { compile(pattern); } catch (UnsupportedRegexException e) { if (e.getMessage().contains(\"too many sequences\")) { /* split alternation into multiple patterns */ } }","preventionTips":["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."],"tags":["regex","tregex","alternation","parser","limit-exceeded"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}