{"record":{"id":"38da6648881533e7","repo":"json-path/JsonPath","slug":"expected-end-of-filter-expression-instead-of-s","errorCode":null,"errorMessage":"Expected end of filter expression instead of: %s","messagePattern":"Expected end of filter expression instead of: (.+?)","errorType":"exception","errorClass":"InvalidPathException","httpStatus":null,"severity":"error","filePath":"json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java","lineNumber":81,"sourceCode":"        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;\n        } catch (InvalidPathException e){\n            throw e;\n        } catch (Exception e) {\n            throw new InvalidPathException(\"Failed to parse filter: \" + filter + \", error on position: \" + filter.position() + \", char: \" + filter.currentChar());\n        }\n    }\n\n    private ValueNode readValueNode() {\n        switch (filter.skipBlanks().currentChar()) {\n            case DOC_CONTEXT  : return readPath();\n            case EVAL_CONTEXT : return readPath();\n            case NOT:\n                filter.incrementPosition(1);\n                switch (filter.skipBlanks().currentChar()) {","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/json-path/JsonPath/blob/62a4c9f0f65ba3f625aa0867d64c528ba72d09ec/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java#L63-L99","documentation":"FilterCompiler.compile() parses the filter expression and then skips blanks; if any characters remain within the '[?(...)]' envelope, the expression is malformed and this InvalidPathException is thrown, naming the leftover text. It means the filter body contained extra tokens after a complete logical expression, e.g. '[?(@.a == 1) @.b]'.","triggerScenarios":"Passing a filter whose inner expression has trailing junk after a parseable expression — extra quotes, an unmatched operand like '[?(@.a == 1 &&)]', duplicated predicates, or concatenated filters '[?(@.a)][?(@.b)]' passed in one string.","commonSituations":"Merging multiple filter predicates by naive string concatenation instead of using Filter.and()/Filter.filter(); typos leaving stray characters; a quote or bracket closing early so the parser stops mid-string.","solutions":["Inspect the leftover text in the message — it points at exactly where the valid expression ends","Combine predicates with Filter.and(Filter, Filter) or Criteria instead of concatenating '[?...] ' strings","Check for early-closing characters (a stray ')' or quote) that end the expression prematurely","Split the path into a base path plus a single '[?(...)]' filter; only one filter per bracket pair is allowed"],"exampleFix":"// before\nJsonPath.compile(\"$..book[?(@.a == 1) @.b == 2]\");\n// after\nJsonPath.compile(\"$..book[?(@.a == 1 && @.b == 2)]\");","handlingStrategy":"validation","validationCode":"static boolean singleFilterExpression(String path) {\n    return path != null && path.indexOf(\"[?\") == path.lastIndexOf(\"[?\"); // one filter per path segment string\n}","typeGuard":null,"tryCatchPattern":"try {\n    return JsonPath.compile(path);\n} catch (InvalidPathException e) {\n    if (e.getMessage().startsWith(\"Expected end of filter expression\")) {\n        throw new IllegalArgumentException(\"Trailing tokens after filter expression in: \" + path, e);\n    }\n    throw e;\n}","preventionTips":["Combine predicates with Filter.and()/Filter.or() instead of concatenating '[?...] [?...]' strings","Keep exactly one expression inside each '[?(...)]' pair","Check the message's leftover text — it marks where the valid expression ended","Compile user/config-provided paths at load time, not at query time"],"tags":["json-path","filter-syntax","expression-parse"],"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"}