json-path/JsonPath · error · InvalidPathException
Filter must start with '[' and end with ']'.
Error message
Filter must start with '[' and end with ']'.
What it means
FilterCompiler validates that a filter expression string starts with '[' and ends with ']' before parsing it. If the trimmed filter string does not have these delimiters, an InvalidPathException with this message is thrown. This is Jayway JsonPath's way of rejecting malformed filter syntax like '?(x)' instead of '[?(x)]'.
Source
Thrown at json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java:61
private static final char TRUE = 't';
private static final char FALSE = 'f';
private static final char NULL = 'n';
private static final char NOT = '!';
private static final char PATTERN = '/';
private static final char IGNORE_CASE = 'i';
private CharacterIndex filter;
public static Filter compile(String filterString) {
FilterCompiler compiler = new FilterCompiler(filterString);
return new CompiledFilter(compiler.compile());
}
private FilterCompiler(String filterString) {
filter = new CharacterIndex(filterString);
filter.trim();
if (!filter.currentCharIs('[') || !filter.lastCharIs(']')) {
throw new InvalidPathException("Filter must start with '[' and end with ']'. " + filterString);
}
filter.incrementPosition(1);
filter.decrementEndPosition(1);
filter.trim();
if (!filter.currentCharIs('?')) {
throw new InvalidPathException("Filter must start with '[?' and end with ']'. " + filterString);
}
filter.incrementPosition(1);
filter.trim();
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();View on GitHub (pinned to 62a4c9f0f6)
Solutions
- Wrap the filter expression in square brackets: the substring passed as a filter must literally begin with '[' and end with ']'
- Check for trailing characters after ']' (spaces are trimmed, but any other character breaks the check)
- If composing dynamically, build the path as "$..book[?(" + predicate + ")]" so brackets are guaranteed
- Verify with a JSONPath evaluator (e.g. https://jsonpath.com) that the query is syntactically valid before embedding it in code
Example fix
// before
JsonPath.compile("$..book?(@.price < 10)");
// after
JsonPath.compile("$..book[?(@.price < 10)]"); Defensive patterns
Strategy: validation
Validate before calling
// alternate concise guard
Objects.requireNonNull(filter);
if (!filter.trim().startsWith("[") || !filter.trim().endsWith("]"))
throw new IllegalArgumentException("Filter must be bracketed"); Prevention
- Validate before compiling; fail fast with your own clearer message
When it happens
Trigger: Calling JsonPath.compile() or Filter/Path building APIs with a filter string whose first non-blank character is not '[' or whose last non-blank character is not ']', e.g. JsonPath.compile("$..book[?(@.price < 10)]") mistyped as "$..book(@.price < 10)" or with a stray trailing character.
Common situations: Hand-written JSONPath strings with missing or unbalanced brackets; filters interpolated from templates or config; trailing whitespace/comments left after the closing bracket in hand-edited query strings.
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.
Related errors
- Filter must start with '[?' and end with ']'.
- Filter must start with '[?(' and end with ')]'.
- Failed to parse operator
- Filter operator is not supported!
- Could not find matching close quote for %s when parsing : %s
AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11).
Data as JSON: /api/errors/4f2bda8f8ea86907.
Report an issue: GitHub.