json-path/JsonPath · error · JsonPathException

Could not determine value type

Error message

Could not determine value type

What it means

ValueNode.toValueNode(Object o) converts an arbitrary Java object into a ValueNode for filter evaluation (strings, characters, numbers, booleans, Patterns, OffsetDateTimes are supported). When the object's type is unrecognized, it throws JsonPathException("Could not determine value type"). This happens when a filter operand or evaluated value is a Java type the converter does not handle, such as Map, List, raw Date, UUID, byte[], or custom POJOs.

Source

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

    //----------------------------------------------------
    //
    // Factory methods
    //
    //----------------------------------------------------
    public static ValueNode toValueNode(Object o){

        if(o == null) return NULL_NODE;
        if(o instanceof ValueNode) return (ValueNode)o;
        if(o instanceof Class) return createClassNode((Class)o);
        else if(isPath(o)) return new PathNode(o.toString(), false, false);
        else if(isJson(o)) return createJsonNode(o.toString());
        else if(o instanceof String) return createStringNode(o.toString(), true);
        else if(o instanceof Character) return createStringNode(o.toString(), false);
        else if(o instanceof Number) return createNumberNode(o.toString());
        else if(o instanceof Boolean) return createBooleanNode(o.toString());
        else if(o instanceof Pattern) return createPatternNode((Pattern)o);
        else if (o instanceof OffsetDateTime) return createOffsetDateTimeNode(o.toString());  //workaround for issue: https://github.com/json-path/JsonPath/issues/613
        else throw new JsonPathException("Could not determine value type");

    }

    public static StringNode createStringNode(CharSequence charSequence, boolean escape){
        return new StringNode(charSequence, escape);
    }

    public static ClassNode createClassNode(Class<?> clazz){
        return new ClassNode(clazz);
    }

    public static NumberNode createNumberNode(CharSequence charSequence){
        return new NumberNode(charSequence);
    }

    public static BooleanNode createBooleanNode(CharSequence charSequence){
        return Boolean.parseBoolean(charSequence.toString()) ? TRUE : FALSE;
    }

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Convert the value to a supported type before evaluation: OffsetDateTime for dates, String/Number/Boolean/Pattern/Character
  2. Convert Maps and Lists to a parsed document via JsonPath.parse()/Configuration before using them as operands
  3. Use the #613 workaround contract: pass OffsetDateTime (not java.util.Date) for datetime comparisons
  4. Catch JsonPathException around evaluation and implement custom conversion logic for your types

Example fix

// before
Date d = new Date();
filter.where("$.created lt " + d); // java.util.Date -> JsonPathException
// after
OffsetDateTime d = OffsetDateTime.now();
filter.where("$.created lt " + d); // supported type
Defensive patterns

Strategy: validation

Validate before calling

static void assertSupportedOperand(Object o) {
    if (!(o instanceof String || o instanceof Character || o instanceof Number || o instanceof Boolean || o instanceof Pattern || o instanceof OffsetDateTime))
        throw new IllegalArgumentException("Unsupported filter operand type: " + o.getClass());
}

Type guard

static boolean isConvertibleToValueNode(Object o) { return o instanceof String || o instanceof Character || o instanceof Number || o instanceof Boolean || o instanceof Pattern || o instanceof OffsetDateTime; }

Try / catch

try {
    return JsonPath.parse(json).read("$.items[?(@.x in [" + operand + "])]");
} catch (JsonPathException e) {
    if (e.getMessage().contains("Could not determine value type")) {
        // convert the operand to a supported type and retry
        return evaluateWithConvertedOperand(json);
    }
    throw e;
}

Prevention

When it happens

Trigger: Passing an unsupported Java object as a filter operand or as a document value that needs conversion: e.g. supplying a java.util.Date or java.util.UUID in a filter parameter, a List/Map not converted by the caller, or a custom type reaching toValueNode during evaluation of a parameterized filter like $.items[?(@.x in ${list})].

Common situations: Using java.util.Date instead of OffsetDateTime for date filters (pre-#613 types unsupported); passing Java 8+ types like UUID or enums; supplying collections that should have been pre-parsed via JsonPath.parse; custom JSON providers producing wrapper objects that leak into toValueNode.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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