json-path/JsonPath · error · InvalidPathException

Expected offsetDateTime node

Error message

Expected offsetDateTime node

What it means

ValueNode's base asOffsetDateTimeNode() throws InvalidPathException("Expected offsetDateTime node") when called on a node that is not an OffsetDateTimeNode. This is the workaround added for GitHub issue json-path/JsonPath#613, enabling date comparisons in filters (e.g. @.date < 2020-01-01T00:00Z). The error means a date-comparison filter received a non-date operand node.

Source

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

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

    public OffsetDateTimeNode asOffsetDateTimeNode(){
        throw new InvalidPathException("Expected offsetDateTime node");
    }


    private static boolean isPath(Object o) {
        if(o == null || !(o instanceof String)){
            return false;
        }
        String str = o.toString().trim();
        if (str.length() <= 0) {
            return false;
        }
        char c0 = str.charAt(0);
        if(c0 == '@' || c0 == '$'){
            try {
                PathCompiler.compile(str);
                return true;
            } catch(Exception e){
                return false;

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Upgrade json-path to a version containing the issue #613 OffsetDateTime workaround so date literals become OffsetDateTimeNode operands
  2. Store dates in ISO-8601 offset format (e.g. 2020-01-01T00:00:00+00:00) in documents and filters so they parse as OffsetDateTime
  3. Compare lexicographically as ISO strings instead of using date operators, or pre-filter in Java code by parsing dates yourself
  4. Catch InvalidPathException and fall back to string/date parsing in application code

Example fix

// before
$.orders[?(@.created < 2020-01-01)] // non-ISO literal, no OffsetDateTimeNode on old versions
// after
$.orders[?(@.created < 2020-01-01T00:00:00+00:00)] // ISO-8601 with offset, on json-path with #613 fix
Defensive patterns

Strategy: validation

Validate before calling

String raw = JsonPath.parse(json).read("$.order.created");
OffsetDateTime.parse(raw); // throws DateTimeParseException if not ISO-8601 with offset
if (raw.contains(" ") || !raw.matches(".*([+-]\d\d:\d\d|Z)$")) throw new IllegalArgumentException("created must be ISO-8601 with offset");

Type guard

static boolean isIsoOffsetDate(String s) { try { OffsetDateTime.parse(s); return true; } catch (DateTimeParseException e) { return false; } }

Try / catch

try {
    return JsonPath.parse(json).read("$.orders[?(@.created < 2020-01-01T00:00:00+00:00)]");
} catch (InvalidPathException e) {
    // fall back to parsing dates in Java and filtering manually
    return manualDateFilter(json);
}

Prevention

When it happens

Trigger: Date-comparison filters where the operand is not an OffsetDateTimeNode — e.g. the compared field is a plain string not parseable/handled as OffsetDateTime, the value wasn't routed through createOffsetDateTimeNode, or the JsonPath version predates/is inconsistent with the issue-613 workaround. Raised from evaluate on date comparisons.

Common situations: Comparing ISO date strings stored in JSON with datetime literals in filters on a JsonPath version lacking the #613 fix (dates treated as plain strings); fields formatted with non-ISO date strings the OffsetDateTime parser rejects; mixing Date and OffsetDateTime representations.

Related errors


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