{"record":{"id":"7b4357d847d13424","repo":"jhy/jsoup","slug":"pattern-syntax-error","errorCode":null,"errorMessage":"Pattern syntax error: ","messagePattern":"Pattern syntax error: ","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/jsoup/helper/Re2jRegex.java","lineNumber":21,"sourceCode":"/**\n re2j-backed Regex implementation; must only be touched when re2j is on the classpath.\n */\nfinal class Re2jRegex extends Regex {\n    private static final java.util.regex.Pattern unused = java.util.regex.Pattern.compile(\"\");\n    private static final String PatternComplexityError = \"Pattern complexity error\";\n\n    private final com.google.re2j.Pattern re2jPattern;\n\n    private Re2jRegex(com.google.re2j.Pattern re2jPattern) {\n        super(unused);\n        this.re2jPattern = re2jPattern;\n    }\n\n    public static Regex compile(String regex) {\n        try {\n            return new Re2jRegex(com.google.re2j.Pattern.compile(regex));\n        } catch (RuntimeException e) {\n            throw new ValidationException(\"Pattern syntax error: \" + e.getMessage());\n        } catch (OutOfMemoryError | StackOverflowError e) { // complex patterns may exhaust VM resources\n            throw new ValidationException(PatternComplexityError);\n        }\n    }\n\n    @Override\n    public Matcher matcher(CharSequence input) {\n        return new Re2jMatcher(re2jPattern.matcher(input));\n    }\n\n    @Override\n    public String toString() {\n        return re2jPattern.toString();\n    }\n\n    private static final class Re2jMatcher implements Matcher {\n        private final com.google.re2j.Matcher delegate;\n","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/jhy/jsoup/blob/9851ac5d9c576c6888910b5a51a2362bbc978959/src/main/java/org/jsoup/helper/Re2jRegex.java#L3-L39","documentation":"Re2jRegex.compile wraps com.google.re2j.Pattern.compile; a RuntimeException from RE2 (typically PatternSyntaxException) is rethrown as ValidationException with 'Pattern syntax error: ' plus the parser's message. It signals the regex string itself could not be parsed.","triggerScenarios":"Passing a pattern with unbalanced parentheses/brackets, a bad escape (e.g. \\\\y), invalid repetition like *{2}, or RE2-unsupported constructs that RE2's parser rejects at compile time.","commonSituations":"Regexes written for PCRE/backtracking engines (lookbehinds, backreferences) that differ syntactically; user-supplied patterns being compiled without validation; escaping errors when building patterns from string concatenation.","solutions":["Fix the regex syntax per the appended parser message (position is usually included)","Test the pattern in an RE2-compatible validator (RE2 lacks backreferences/lookarounds)","Validate/compile user-supplied patterns at input time with try/catch around compile","Use Pattern.quote() for literal text fragments"],"exampleFix":"// before\nRegex r = Re2jRegex.compile(\"(?<=foo)bar\");\n// after\nRegex r = Re2jRegex.compile(\"(?:^|foo)(bar)\"); // RE2-compatible: no lookbehind","handlingStrategy":"validation","validationCode":"try { com.google.re2j.Pattern.compile(userRegex); } catch (RuntimeException e) { throw new IllegalArgumentException(\"Invalid regex: \" + e.getMessage()); }","typeGuard":"boolean isValidRe2(String pattern) { try { com.google.re2j.Pattern.compile(pattern); return true; } catch (RuntimeException e) { return false; } }","tryCatchPattern":"try { Regex r = Re2jRegex.compile(pattern); } catch (ValidationException e) { /* show e.getMessage() to the user / reject input */ }","preventionTips":["Validate patterns at input boundaries before storing","Avoid PCRE-only syntax (lookarounds, backreferences) since RE2 rejects them","Keep a regex test suite covering user-supplied patterns"],"tags":["regex","validation","re2"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"9851ac5d9c576c6888910b5a51a2362bbc978959","analyzedAt":"2026-09-08T15:22:04.931Z","contentChangedAt":"2026-09-08T15:22:04.931Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}