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
- Add the missing closing slash to terminate the regex literal in the path.
- Escape any literal slashes inside the regex with a backslash (\/) so they are not mistaken for the terminator.
- Pre-test the regex pattern standalone before embedding it into the filter expression.
- 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
- Escape literal slashes inside regex filters as \/
- Test the regex pattern in isolation before embedding it
- Build regex filters from a helper that guarantees surrounding slashes
- Never hand-edit the closing slash out of =~ /pattern/ filters
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
- Could not find matching close quote for %s when parsing : %s
- Expected character: %c
- Filter must start with '[' and end with ']'.
- Filter must start with '[?' and end with ']'.
- Filter must start with '[?(' and end with ')]'.
AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11).
Data as JSON: /api/errors/b3b7c2a6d5ac556e.
Report an issue: GitHub.