json-path/JsonPath · error · JsonPathException

Could not convert

Error message

Could not convert 

What it means

When evaluating a filter ValueNode created from a path (PathJsonPathValueNode-style), the library evaluates the sub-path against the document and converts the result into a ValueNode (String, Boolean, JsonNode, etc.). If the result's type is none of the supported shapes (Number/String/Boolean/OffsetDateTime/null/array/map), it throws JsonPathException('Could not convert ... to a ValueNode').

Source

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

                    Object res;
                    if (ctx instanceof PredicateContextImpl) {
                        //This will use cache for document ($) queries
                        PredicateContextImpl ctxi = (PredicateContextImpl) ctx;
                        res = ctxi.evaluate(path);
                    } else {
                        Object doc = path.isRootPath() ? ctx.root() : ctx.item();
                        res = path.evaluate(doc, ctx.root(), ctx.configuration()).getValue();
                    }
                    res = ctx.configuration().jsonProvider().unwrap(res);

                    if (res instanceof Number) return ValueNode.createNumberNode(res.toString());
                    else if (res instanceof String) return ValueNode.createStringNode(res.toString(), false);
                    else if (res instanceof Boolean) return ValueNode.createBooleanNode(res.toString());
                    else if (res instanceof OffsetDateTime) return ValueNode.createOffsetDateTimeNode(res.toString()); //workaround for issue: https://github.com/json-path/JsonPath/issues/613
                    else if (res == null) return NULL_NODE;
                    else if (ctx.configuration().jsonProvider().isArray(res)) return ValueNode.createJsonNode(ctx.configuration().mappingProvider().map(res, List.class, ctx.configuration()));
                    else if (ctx.configuration().jsonProvider().isMap(res)) return ValueNode.createJsonNode(ctx.configuration().mappingProvider().map(res, Map.class, ctx.configuration()));
                    else throw new JsonPathException("Could not convert " + res.getClass().toString()+":"+ res.toString() + " to a ValueNode");
                } catch (PathNotFoundException e) {
                    return UNDEFINED;
                }
            }
        }
    }
}

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Upgrade json-path to a version whose ValueNode supports numeric conversion, or ensure the compared value is a String/Boolean/List/Map.
  2. Configure Configuration with a MappingProvider that maps values to standard Java types (e.g. JacksonMappingProvider).
  3. Cast the comparison operand to a supported type in the predicate, e.g. compare strings instead of raw numbers.
  4. Catch JsonPathException and fall back to evaluating the predicate in application code.

Example fix

// before
JsonPath.parse(json).set("$[?(@.count == 5)].status", "ok"); // count maps to Integer -> not convertible (old versions)
// after
Configuration cfg = Configuration.builder().mappingProvider(new JacksonMappingProvider()).build();
JsonPath.using(cfg).parse(json).set("$[?(@.count == 5)].status", "ok");
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = JsonPath.read(json, operandPath);
if (!(v instanceof String || v instanceof Boolean || v instanceof List || v instanceof Map || v == null)) {
    throw new IllegalStateException("Operand type not convertible to ValueNode: " + v.getClass());
}

Type guard

boolean isValueNodeConvertible(Object v) {
    return v == null || v instanceof String || v instanceof Boolean
        || v instanceof List || v instanceof Map;
}

Try / catch

try {
    JsonPath.read(json, path);
} catch (JsonPathException e) {
    if (e.getMessage().startsWith("Could not convert")) { /* handle type mismatch */ }
}

Prevention

When it happens

Trigger: A filter operand path resolves to an unexpected runtime type — typically a Number (older versions without a numeric branch) or a custom object returned by a MappingProvider — inside a predicate such as [?(@.a.b == 3)] where @.a.b evaluates to an Integer/Double not handled by the conversion chain.

Common situations: Comparing against numeric fields with older json-path versions (numbers were not convertible), using a custom MappingProvider/Configuration that returns domain objects instead of primitives/maps/lists, or documents parsed with a provider producing non-standard types.

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/b89a949bd7ce3554. Report an issue: GitHub.