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

  1. Adjust the filter to check for the concrete value present instead of expecting absence, e.g. @.field == '' for empty strings
  2. Ensure optional fields are actually omitted (not set to placeholders) if logic relies on undefined semantics
  3. Handle both undefined and default-value cases in the predicate, e.g. @.field == null || @.field == ''
  4. 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

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


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