json-path/JsonPath · error · InvalidPathException

Expected value list node

Error message

Expected value list node

What it means

ValueNode's base asValueListNode() throws InvalidPathException("Expected value list node") when a node that is not a ValueListNode is cast via asValueListNode(). ValueListNode represents a list of value operands used by operators like in/contains/all (callers: evaluate, requiredValues, shouldContainAll, res, listNode). It is thrown when such an operator receives a single scalar node instead of a value-list operand.

Source

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

    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");
    }

    public UndefinedNode asUndefinedNode() {
        throw new InvalidPathException("Expected undefined node");
    }

    public boolean isUndefinedNode() {
        return false;
    }

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Provide the operand as a JSON array: $.items[?(@.tag in ['a','b'])]
  2. Ensure the field being iterated (e.g. tags) is an array in the document; normalize scalars to single-element arrays before filtering
  3. Use equality (==) instead of in/contains when the value is genuinely a scalar
  4. Catch InvalidPathException and treat items with non-array fields as non-matching

Example fix

// before
$.items[?(@.tag in 'a')]  // scalar operand, not a value list
// after
$.items[?(@.tag in ['a'])]
Defensive patterns

Strategy: validation

Validate before calling

Object v = JsonPath.parse(json).read("$.item.tags");
if (v != null && !(v instanceof List)) throw new IllegalArgumentException("tags must be an array for in/contains operators");

Type guard

static boolean isListOperand(Object o) { return o instanceof List; }

Try / catch

try {
    return JsonPath.parse(json).read("$.items[?(@.tag in ['a','b'])]");
} catch (InvalidPathException e) {
    return Collections.emptyList(); // non-list operand
}

Prevention

When it happens

Trigger: Using array operators (in, contains, all, size comparisons) where the operand list was not built as a ValueListNode — e.g. @.x in 'a' with a scalar instead of a list ['a','b'], or evaluating against a field that is a scalar rather than an array when the operator iterates values.

Common situations: Filters like $.items[?(@.tags in ['a','b'])] evaluated on records where tags is null or a single string instead of an array; mixing single-value and list operands in 'contains'/'in' checks.

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/dd1315750fc6334f. Report an issue: GitHub.