json-path/JsonPath · error · InvalidPathException

Expected predicate node

Error message

Expected predicate node

What it means

ValueNode's base asPredicateNode() throws InvalidPathException("Expected predicate node") when evaluate calls asPredicateNode() on a node that is not a PredicateNode. PredicateNode wraps a nested [?( ... )] predicate used as an operand inside an outer filter; this error means the operand was a plain value instead of a predicate expression.

Source

Thrown at json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java:72

    public BooleanNode asBooleanNode() {
        throw new InvalidPathException("Expected boolean node");
    }

    public boolean isJsonNode() {
        return false;
    }

    public JsonNode asJsonNode() {
        throw new InvalidPathException("Expected json node");
    }

    public boolean isPredicateNode() {
        return false;
    }

    public PredicateNode asPredicateNode() {
        throw new InvalidPathException("Expected predicate node");
    }

    public boolean isValueListNode() {
        return false;
    }

    public ValueListNode asValueListNode() {
        throw new InvalidPathException("Expected value list node");
    }

    public boolean isNullNode() {
        return false;
    }

    public NullNode asNullNode() {
        throw new InvalidPathException("Expected null node");
    }

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Correct the filter syntax so nested predicates are wrapped as [?( ... )], e.g. $.items[?(@.sub[?(@.ok == true)])]
  2. Verify the operand path actually targets an array that can host a nested predicate
  3. Simplify the expression into two sequential filter steps applied one after the other
  4. Catch InvalidPathException around evaluation to surface a clear message about malformed predicates

Example fix

// before
$.items[?(@.tags contains @.required == true)] // operand is scalar, not predicate
// after
$.items[?(@.tags[?(@ == 'x')])] // proper nested predicate form
Defensive patterns

Strategy: validation

Validate before calling

// validate nested predicate syntax before evaluation
String expr = "$.items[?(@.tags[?(@ == 'x')])]";
if (!expr.contains("[?(")) throw new IllegalArgumentException("nested predicate must be wrapped in [?( ... )]");

Try / catch

try {
    return JsonPath.parse(json).read(expr);
} catch (InvalidPathException e) {
    throw new IllegalArgumentException("Malformed nested predicate in filter: " + expr, e);
}

Prevention

When it happens

Trigger: Using a nested filter/predicate as an operand where the evaluated node is a plain ValueNode rather than a PredicateNode — i.e. the expression grammar expected [?(@.x)] as an operand but evaluation produced a scalar. Triggered from ValueNode.evaluate in the filter evaluation machinery.

Common situations: Complex/nested filter expressions where an inner expression was written incorrectly (missing [?()] wrapper) or an operand path resolves to a scalar instead of a predicate context; hand-built filter expressions with syntax mistakes.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11). Data as JSON: /api/errors/3552307c20d5f911. Report an issue: GitHub.