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
- Provide the operand as a JSON array: $.items[?(@.tag in ['a','b'])]
- Ensure the field being iterated (e.g. tags) is an array in the document; normalize scalars to single-element arrays before filtering
- Use equality (==) instead of in/contains when the value is genuinely a scalar
- 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
- Always pass array literals for in/contains operands: ['a','b']
- Normalize scalar fields to single-element arrays before filtering
- Use == for genuinely scalar comparisons instead of in/contains
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
- Expected string node
- Expected boolean node
- Expected json node
- Expected predicate node
- Expected null node
AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11).
Data as JSON: /api/errors/dd1315750fc6334f.
Report an issue: GitHub.