jhy/jsoup · error · ValidationException

Pattern syntax error:

Error message

Pattern syntax error: 

What it means

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.

Solutions

  1. Fix the regex syntax per the appended parser message (position is usually included)
  2. Test the pattern in an RE2-compatible validator (RE2 lacks backreferences/lookarounds)
  3. Validate/compile user-supplied patterns at input time with try/catch around compile
  4. Use Pattern.quote() for literal text fragments

Example fix

// before
Regex r = Re2jRegex.compile("(?<=foo)bar");
// after
Regex r = Re2jRegex.compile("(?:^|foo)(bar)"); // RE2-compatible: no lookbehind
Defensive patterns

Strategy: validation

Validate before calling

try { com.google.re2j.Pattern.compile(userRegex); } catch (RuntimeException e) { throw new IllegalArgumentException("Invalid regex: " + e.getMessage()); }

Type guard

boolean isValidRe2(String pattern) { try { com.google.re2j.Pattern.compile(pattern); return true; } catch (RuntimeException e) { return false; } }

Try / catch

try { Regex r = Re2jRegex.compile(pattern); } catch (ValidationException e) { /* show e.getMessage() to the user / reject input */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of jhy/jsoup@9851ac5d9c (2026-09-08). Data as JSON: /api/errors/7b4357d847d13424. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/org/jsoup/helper/Re2jRegex.java:21

/**
 re2j-backed Regex implementation; must only be touched when re2j is on the classpath.
 */
final class Re2jRegex extends Regex {
    private static final java.util.regex.Pattern unused = java.util.regex.Pattern.compile("");
    private static final String PatternComplexityError = "Pattern complexity error";

    private final com.google.re2j.Pattern re2jPattern;

    private Re2jRegex(com.google.re2j.Pattern re2jPattern) {
        super(unused);
        this.re2jPattern = re2jPattern;
    }

    public static Regex compile(String regex) {
        try {
            return new Re2jRegex(com.google.re2j.Pattern.compile(regex));
        } catch (RuntimeException e) {
            throw new ValidationException("Pattern syntax error: " + e.getMessage());
        } catch (OutOfMemoryError | StackOverflowError e) { // complex patterns may exhaust VM resources
            throw new ValidationException(PatternComplexityError);
        }
    }

    @Override
    public Matcher matcher(CharSequence input) {
        return new Re2jMatcher(re2jPattern.matcher(input));
    }

    @Override
    public String toString() {
        return re2jPattern.toString();
    }

    private static final class Re2jMatcher implements Matcher {
        private final com.google.re2j.Matcher delegate;

View on GitHub (pinned to 9851ac5d9c)