json-path/JsonPath · error · InvalidPathException

Could not find matching close for %s when parsing regex in :

Error message

Could not find matching close for %s when parsing regex in : %s

What it means

indexOfMatchingCloseChar also supports regex literals inside path filters (a leading slash opens a regex region, detected when skipRegex is true). It uses nextIndexOfUnescaped to locate the closing unescaped slash; if it reaches the end of the input without finding one, it throws InvalidPathException because the regex literal is never terminated.

Source

Thrown at json-path/src/main/java/com/jayway/jsonpath/internal/CharacterIndex.java:112

        int opened = 1;
        int readPosition = startPosition + 1;
        while (inBounds(readPosition)) {
            if (skipStrings) {
                char quoteChar = charAt(readPosition);
                if (quoteChar == SINGLE_QUOTE || quoteChar == DOUBLE_QUOTE){
                    readPosition = nextIndexOfUnescaped(readPosition, quoteChar);
                    if(readPosition == -1){
                        throw new InvalidPathException("Could not find matching close quote for " + quoteChar + " when parsing : " + charSequence);
                    }
                    readPosition++;
                }
            }
            if (skipRegex) {
                if (charAt(readPosition) == REGEX) {
                    readPosition = nextIndexOfUnescaped(readPosition, REGEX);
                    if(readPosition == -1){
                        throw new InvalidPathException("Could not find matching close for " + REGEX + " when parsing regex in : " + charSequence);
                    }
                    readPosition++;
                }
            }
            if (charAt(readPosition) == openChar) {
                opened++;
            }
            if (charAt(readPosition) == closeChar) {
                opened--;
                if (opened == 0) {
                    return readPosition;
                }
            }
            readPosition++;
        }
        return -1;
    }

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Add the missing closing slash to terminate the regex literal in the path.
  2. Escape any literal slashes inside the regex with a backslash (\/) so they are not mistaken for the terminator.
  3. Pre-test the regex pattern standalone before embedding it into the filter expression.
  4. Use JsonPath.compile() on the generated path early to surface the syntax error at a well-defined point.

Example fix

// before
String path = "$[?(@.url =~ /https://example)]"; // unescaped slashes end the regex early / leave it open
// after
String path = "$[?(@.url =~ /https:\\/\\/example/)]";
Defensive patterns

Strategy: validation

Validate before calling

boolean regexOpen = false;
for (int i = 0; i < path.length(); i++) {
    if (path.charAt(i) == '/' && (i == 0 || path.charAt(i - 1) != '\\')) regexOpen = !regexOpen;
}
if (regexOpen) throw new IllegalArgumentException("Unterminated regex literal in path: " + path);
JsonPath.compile(path);

Try / catch

try {
    return JsonPath.compile(path);
} catch (InvalidPathException e) {
    if (e.getMessage().contains("regex")) {
        throw new IllegalArgumentException("Regex literal in path is not terminated: " + path, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Evaluating a filter path containing a regex pattern like /[.../ or ~regex segments where the closing slash was omitted or escaped incorrectly, e.g. "$[?(@.name =~ /abc)]" with the trailing slash deleted.

Common situations: Hand-written regex filters where the trailing slash is lost during editing; regex patterns built programmatically where the source pattern already contains slashes or escapes; mistaking a regex character class containing a slash for a terminator.

Related errors


AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11). Data as JSON: /api/errors/b3b7c2a6d5ac556e. Report an issue: GitHub.