json-path/JsonPath · error · InvalidPathException
Expected json node
Error message
Expected json node
What it means
ValueNode's base asJsonNode() throws InvalidPathException("Expected json node") when code (evaluate, vn, valueNode paths) calls asJsonNode() on a node that is not a JsonNode (a node wrapping a parsed document). This happens when a filter expects an embedded document/array operand but gets a scalar ValueNode such as a string or number. It is part of JsonPath's default-throw type-cast family on ValueNode.
Source
Thrown at json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java:64
public StringNode asStringNode() {
throw new InvalidPathException("Expected string node");
}
public boolean isBooleanNode() {
return false;
}
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");
}
View on GitHub (pinned to 62a4c9f0f6)
Solutions
- Ensure the operand field is a real JSON object/array in the document (parse embedded JSON strings before evaluation)
- Rewrite the filter to operate on the nested field's properties rather than on the whole document value
- Validate the document shape (e.g. that the field is an object) before running the filter
- Catch InvalidPathException and fall back to scalar-comparison logic
Example fix
// before
String meta = "{}"; // embedded JSON stored as string; filter @.meta in @.defaults fails
// after
Object meta = JsonPath.parse(metaJsonString).json(); // real object node; filter works Defensive patterns
Strategy: type-guard
Validate before calling
Object v = JsonPath.parse(json).read("$.item.meta");
if (!(v instanceof Map) && !(v instanceof List)) throw new IllegalArgumentException("meta must be a JSON object or array"); Type guard
static boolean isDocumentOperand(Object o) { return o instanceof Map || o instanceof List; } Try / catch
try {
return JsonPath.parse(json).read("$.items[?(@.meta in @.defaults)]");
} catch (InvalidPathException e) {
// operand is scalar, not a document; fallback to scalar logic
return fallbackScalarFilter(json);
} Prevention
- Parse embedded JSON strings into real objects before filtering
- Validate the document schema (object/array fields) before running document-operand filters
- Avoid operators that expect whole-document operands when the field may be scalar
When it happens
Trigger: A filter or API expecting a nested document operand — e.g. an operator that calls asJsonNode() on the evaluated value of a path — receiving a scalar, e.g. $.items[?(@.meta in @.defaults)] where @.meta resolves to a string instead of an object/array. Also direct calls to valueNode()/vn conversion paths on non-document values.
Common situations: Comparing or nesting whole sub-documents in filters when some records store the field as a JSON string rather than a parsed object; schema drift where an array field sometimes holds a plain value.
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 predicate node
- Expected value list node
- Expected null node
AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11).
Data as JSON: /api/errors/b16800ba2805ca4c.
Report an issue: GitHub.