{"record":{"id":"1c6461d041564a46","repo":"oracle/graal","slug":"parse-tree-explosion","errorCode":null,"errorMessage":"parse tree explosion","messagePattern":"parse tree explosion","errorType":"exception","errorClass":"UnsupportedRegexException","httpStatus":null,"severity":"error","filePath":"regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/parser/Counter.java","lineNumber":91,"sourceCode":"        count -= i;\n        return ret;\n    }\n\n    public static class ThresholdCounter extends Counter {\n\n        private final int max;\n        private final String errorMsg;\n\n        public ThresholdCounter(int max, String errorMsg) {\n            this.max = max;\n            this.errorMsg = errorMsg;\n        }\n\n        @Override\n        public int inc(int i) {\n            final int ret = super.inc(i);\n            if (getCount() > max) {\n                throw new UnsupportedRegexException(errorMsg);\n            }\n            return ret;\n        }\n    }\n\n    public static class ThreadSafeCounter extends Counter {\n\n        @Override\n        public int inc() {\n            int c = count;\n            if (c < Integer.MAX_VALUE) {\n                count = c + 1;\n            }\n            return count;\n        }\n\n        @Override\n        public int inc(int i) {","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/parser/Counter.java#L73-L109","documentation":"Thrown by ThresholdCounter during regex AST construction (RegexAST.java:121) when the number of parse-tree nodes exceeds the MaxParserTreeSize option (default TRegexOptions.TRegexParserTreeMaxSize). It is a hard size guard: TRegex refuses to build an AST for patterns so large that compilation cost or memory use would explode. The throw is an UnsupportedRegexException, the standard 'this pattern is too complex for TRegex' signal.","triggerScenarios":"Parsing a pattern with a very large number of AST nodes: deeply nested groups, huge character classes, or machine-generated patterns (e.g. alternations of thousands of literals). The counter increments per node created in RegexAST, so any API that compiles a regex source (RegexCompiler via a Truffle regex language) triggers it once nodeCount > MaxParserTreeSize.","commonSituations":"Generated/programmatic regexes (keyword lists joined with |), JSON-schema-derived patterns, obfuscated or minified patterns embedded in scraped JS, or users lowering MaxParserTreeSize for tests (as RubyTests does with 'MaxParserTreeSize=10000') and then feeding it a normal pattern.","solutions":["Simplify or split the pattern: replace long literal alternations with a trie-like grouping or match them in guest-language code instead of one regex.","Raise the limit at compile time via the RegexOptions string, e.g. append 'MaxParserTreeSize=10000' (option key RegexOptions.MAX_PARSER_TREE_SIZE_NAME); in Truffle settings it appears as regexDummyLang.MaxParserTreeSize.","Catch UnsupportedRegexException at the compilation call site and fall back to a simpler matcher (backtracking engine or literal search)."],"exampleFix":"// before\nObject result = regexLanguage.parse(sourceWithHugePattern);\n\n// after\ntry {\n    Object result = regexLanguage.parse(source);\n} catch (UnsupportedRegexException e) {\n    // pattern exceeds parser limits; use fallback matcher\n    throw new PatternSyntaxException(\"pattern too large: \" + source.getFlags(), e);\n}","handlingStrategy":"try-catch","validationCode":"// Pre-compile pattern at startup / cache site before hot use\ntry {\n    Object compiled = compiler.compile(source, options);\n} catch (UnsupportedRegexException e) {\n    // decide: reject input, or lower MaxParserTreeSize pressure\n}","typeGuard":null,"tryCatchPattern":"catch (UnsupportedRegexException e) — it extends AbstractTruffleException; catch it at the regex-compilation boundary, log source name/pattern hash, and fall back to a guest-language backtracking matcher or reject the input pattern.","preventionTips":["Pre-compile all known regexes at application startup so limits surface during boot, not in production traffic.","Keep generated patterns small: build tries/sets for keyword lists instead of giant alternations.","Tune via RegexOptions string 'MaxParserTreeSize=<n>' when a slightly larger pattern is legitimately needed."],"tags":["regex","parsing","complexity-limit","truffle","tregex"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}