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
- Upgrade json-path to a version containing the issue #613 OffsetDateTime workaround so date literals become OffsetDateTimeNode operands
- 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
- Compare lexicographically as ISO strings instead of using date operators, or pre-filter in Java code by parsing dates yourself
- 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
- Upgrade json-path to a release containing the issue #613 OffsetDateTime workaround
- Store and compare dates only in ISO-8601 offset format
- Never mix java.util.Date with JsonPath date filters; convert to OffsetDateTime first
- Test date filters against your actual document date formats
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
- 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/eb88d4d9fb5af539.
Report an issue: GitHub.