json-path/JsonPath · error · InvalidPathException
Expected undefined node
Error message
Expected undefined node
What it means
ValueNode's base asUndefinedNode() throws InvalidPathException("Expected undefined node") when called on a node that is not an UndefinedNode. UndefinedNode represents a missing/absent value during filter evaluation; the base class throws by default since only UndefinedNode supports this downcast. It fires when evaluation logic requires an 'undefined' operand but receives a concrete value node.
Source
Thrown at json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java:92
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;
}
public boolean isClassNode() {
return false;
}
public ClassNode asClassNode() {
throw new InvalidPathException("Expected class node");
}
//workaround for issue: https://github.com/json-path/JsonPath/issues/613
public boolean isOffsetDateTimeNode(){
return false;
}View on GitHub (pinned to 62a4c9f0f6)
Solutions
- Adjust the filter to check for the concrete value present instead of expecting absence, e.g. @.field == '' for empty strings
- Ensure optional fields are actually omitted (not set to placeholders) if logic relies on undefined semantics
- Handle both undefined and default-value cases in the predicate, e.g. @.field == null || @.field == ''
- Catch InvalidPathException around evaluation when distinguishing missing vs present values
Example fix
// before $.items[?(@.nickname == null)] // nickname exists as empty string; not undefined/null // after $.items[?(@.nickname == null || @.nickname == '')]
Defensive patterns
Strategy: type-guard
Validate before calling
Map<String,Object> item = JsonPath.parse(json).read("$.item");
boolean undefined = !item.containsKey("nickname"); // distinguish absent vs present-with-default Type guard
static boolean isUndefined(DocumentContext ctx, String path) { try { return ctx.read(path) == null && !((Map)ctx.json()).containsKey(lastKey(path)); } catch (PathNotFoundException e) { return true; } } Try / catch
try {
return JsonPath.parse(json).read("$.items[?(@.nickname == null || @.nickname == '')]");
} catch (InvalidPathException e) {
return Collections.emptyList();
} Prevention
- Decide explicitly whether optional fields are omitted or set to placeholders
- Write filters covering both undefined and default-value cases
- Keep schema stable across versions to avoid undefined/present drift
When it happens
Trigger: Filter logic distinguishing missing fields from null where the operand is a concrete value — e.g. an operator or code path calling asUndefinedNode() on a StringNode/NumberNode; expressions whose semantics assume the field is absent but the field actually exists in the document.
Common situations: Schema drift where a previously missing (undefined) field is now present with an empty value, so code that assumed UndefinedNode breaks; custom operators on the internal ValueNode API.
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 value list node
AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11).
Data as JSON: /api/errors/5cf86ac8f1d24cbb.
Report an issue: GitHub.