json-path/JsonPath · error · InvalidPathException
Failed to parse filter:
Error message
Failed to parse filter:
What it means
compile() catches any unexpected exception during parsing (IndexOutOfBounds, NumberFormat, etc.) and rethrows it as InvalidPathException with 'Failed to parse filter:' plus the filter text, position, and offending character. This is the catch-all for filter bodies that are structurally parenthesized correctly but contain invalid expressions — bad literals, stray operators, or unbalanced inner brackets.
Source
Thrown at json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java:89
if (!filter.currentCharIs('(') || !filter.lastCharIs(')')) {
throw new InvalidPathException("Filter must start with '[?(' and end with ')]'. " + filterString);
}
}
public Predicate compile() {
try {
final ExpressionNode result = readLogicalOR();
filter.skipBlanks();
if (filter.inBounds()) {
throw new InvalidPathException(String.format("Expected end of filter expression instead of: %s",
filter.subSequence(filter.position(), filter.length())));
}
return result;
} catch (InvalidPathException e){
throw e;
} catch (Exception e) {
throw new InvalidPathException("Failed to parse filter: " + filter + ", error on position: " + filter.position() + ", char: " + filter.currentChar());
}
}
private ValueNode readValueNode() {
switch (filter.skipBlanks().currentChar()) {
case DOC_CONTEXT : return readPath();
case EVAL_CONTEXT : return readPath();
case NOT:
filter.incrementPosition(1);
switch (filter.skipBlanks().currentChar()) {
case DOC_CONTEXT : return readPath();
case EVAL_CONTEXT : return readPath();
default: throw new InvalidPathException(String.format("Unexpected character: %c", NOT));
}
default : return readLiteral();
}
}
View on GitHub (pinned to 62a4c9f0f6)
Solutions
- Read the reported position and char in the message to locate the offending token
- Fix the operator syntax: JsonPath supports ==, !=, <, <=, >, >=, =~, in, nin, size, empty, matches, and logical &&/||
- Balance all quotes in string literals inside the filter; prefer double quotes escaped correctly in Java source
- Simplify the filter into smaller Criteria and combine with Criteria.and()/or() to isolate the malformed part
- Pin/check library version — newer releases emit more precise errors for the same input
Example fix
// before
JsonPath.compile("$..book[?(@.name === 'x')]");
// after
JsonPath.compile("$..book[?(@.name == 'x')]"); Defensive patterns
Strategy: try-catch
Validate before calling
static boolean hasBalancedQuotes(String filter) {
int q = 0;
for (char c : filter.toCharArray()) { if (c == '\'') q++; }
return q % 2 == 0;
} Try / catch
try {
return JsonPath.compile(path);
} catch (InvalidPathException e) {
if (e.getMessage().startsWith("Failed to parse filter")) {
log.error("Filter parse failed at reported position: {}", e.getMessage());
throw new IllegalArgumentException("Unsupported filter expression: " + path, e);
}
throw e;
} Prevention
- Use only JsonPath-supported operators (==, !=, <, <=, >, >=, =~, in, nin, size, empty, matches) — no JavaScript '==='
- Check quote balance in string literals inside filters
- Build complex predicates with Criteria.and()/or() to avoid hand-assembled expression bugs
- Compile all query strings in a test suite; re-run when bumping the JsonPath version
When it happens
Trigger: A filter body that throws during tokenization: e.g. '[?(@.price < )]' (missing operand), '[?(@.a === 1)]' (unsupported operator), unmatched quote "[?(@.name == 'x)]", or a regex/inline value the parser cannot handle.
Common situations: Typos in operators (===, =>) copied from JavaScript; unbalanced quotes in string literals; nested JSON in comparisons without proper quoting; upgrading JsonPath versions where stricter parsing rejects previously lenient filters.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Expected end of filter expression instead of: %s
- Filter must start with '[' and end with ']'.
- Filter must start with '[?' and end with ']'.
- Filter must start with '[?(' and end with ')]'.
- Failed to parse operator
AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11).
Data as JSON: /api/errors/3772054dd99d887a.
Report an issue: GitHub.