{"record":{"id":"d0e0b5647b339187","repo":"json-path/JsonPath","slug":"filter-must-start-with-and-end-with-d0e0b5","errorCode":null,"errorMessage":"Filter must start with '[?' and end with ']'. ","messagePattern":"Filter must start with '\\[\\?' and end with '\\]'\\. ","errorType":"exception","errorClass":"InvalidPathException","httpStatus":null,"severity":"error","filePath":"json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java","lineNumber":67,"sourceCode":"\n    private CharacterIndex filter;\n\n    public static Filter compile(String filterString) {\n        FilterCompiler compiler = new FilterCompiler(filterString);\n        return new CompiledFilter(compiler.compile());\n    }\n\n    private FilterCompiler(String filterString) {\n        filter = new CharacterIndex(filterString);\n        filter.trim();\n        if (!filter.currentCharIs('[') || !filter.lastCharIs(']')) {\n            throw new InvalidPathException(\"Filter must start with '[' and end with ']'. \" + filterString);\n        }\n        filter.incrementPosition(1);\n        filter.decrementEndPosition(1);\n        filter.trim();\n        if (!filter.currentCharIs('?')) {\n            throw new InvalidPathException(\"Filter must start with '[?' and end with ']'. \" + filterString);\n        }\n        filter.incrementPosition(1);\n        filter.trim();\n        if (!filter.currentCharIs('(') || !filter.lastCharIs(')')) {\n            throw new InvalidPathException(\"Filter must start with '[?(' and end with ')]'. \" + filterString);\n        }\n    }\n\n    public Predicate compile() {\n        try {\n             final ExpressionNode result = readLogicalOR();\n             filter.skipBlanks();\n             if (filter.inBounds()) {\n                 throw new InvalidPathException(String.format(\"Expected end of filter expression instead of: %s\",\n                         filter.subSequence(filter.position(), filter.length())));\n             }\n\n             return result;","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/json-path/JsonPath/blob/62a4c9f0f65ba3f625aa0867d64c528ba72d09ec/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java#L49-L85","documentation":"After confirming the filter starts with '[' and ends with ']', FilterCompiler trims both and requires the first character to be '?'. A filter like '[(@.price < 10)]' (missing the question mark) fails this check and throws this InvalidPathException. Filters in JsonPath must follow the [?(<expression>)] form.","triggerScenarios":"Passing a filter string like '[(@.x == 1)]' or '[...]' (no '?') to JsonPath.compile(), a path string ending in '[...]' used as a filter predicate, or FilterCompiler.compile via public Path APIs.","commonSituations":"Confusing script expression syntax '[...]' with filter syntax '[?(...)]' when copying examples from other JSONPath dialects; dropping the '?' during manual editing.","solutions":["Insert '?' after the opening bracket: '[?(...)]' is the required filter form","Do not confuse script expressions '[(@.length-1)]' with filters; if you want a filter, add '?'","Re-check the dialect of any copied JSONPath snippet — Goessner-style docs mix '[?(...)]' and other bracket forms","Validate the path with a quick compile() in a unit test before shipping it in config"],"exampleFix":"// before\nJsonPath.compile(\"$..book[(@.price < 10)]\");\n// after\nJsonPath.compile(\"$..book[?(@.price < 10)]\");","handlingStrategy":"validation","validationCode":"static boolean isFilterForm(String filter) {\n    String t = filter == null ? \"\" : filter.trim();\n    return t.startsWith(\"[?\") && t.endsWith(\"]\");\n}","typeGuard":"boolean hasQuestionMarkFilter(String path) { return path != null && path.matches(\".*\\\\[\\\\?\\\\(.*\\\\)\\\\].*\"); }","tryCatchPattern":"try {\n    return JsonPath.compile(path);\n} catch (InvalidPathException e) {\n    if (e.getMessage().contains(\"must start with '[?'\")) {\n        throw new IllegalArgumentException(\"Filter missing '?': use [?(...)] in \" + path, e);\n    }\n    throw e;\n}","preventionTips":["Remember: '[' alone is a script/index expression; filters always need '[?'","Never confuse Goessner script expressions '[(@.length-1)]' with filter predicates","Lint JSONPath strings in config at startup by compiling them once"],"tags":["json-path","filter-syntax","invalid-path"],"backgroundTag":"invalid-argument-format","analyzedSha":"62a4c9f0f65ba3f625aa0867d64c528ba72d09ec","analyzedAt":"2026-09-11T11:36:00.448Z","contentChangedAt":"2026-09-11T11:36:00.448Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}