json-path/JsonPath · error · JsonPathException

length operation can not applied to null

Error message

length operation can not applied to null

What it means

JacksonJsonNodeJsonProvider.length throws JsonPathException when the target object is not a type that supports length() (Array, Map, Collection, TextNode). The message "length operation can not applied to null" (or a class name) means the JsonPath length() function was evaluated on an object that is null or of an unsupported node type (e.g. IntNode, BooleanNode).

Solutions

  1. Make the path definite (e.g. $.items[*]) or check the node for null/exists before applying length()
  2. Add a filter guard like ?(@.items != null) or use a default value so length() only runs on present arrays/strings
  3. Verify the JSON shape: if the value is a scalar number, compute length differently or fix the schema/producer
  4. Catch JsonPathException around the length evaluation and treat it as 'length undefined'

Example fix

// before
Integer n = JsonPath.read(json, "$.maybeArray.length()");
// after
List<Object> arr = JsonPath.read(json, "$.maybeArray");
Integer n = (arr == null) ? 0 : arr.size();
Defensive patterns

Strategy: validation

Validate before calling

Object node = JsonPath.read(json, "$.items");
boolean lengthApplies = node != null
    && (node instanceof List || node instanceof Map || node instanceof String || node instanceof TextNode);
if (!lengthApplies) throw new IllegalStateException("length() not applicable to: " + node);

Type guard

static boolean supportsLength(Object o) {
    return o != null && (o instanceof List || o instanceof Map
        || o instanceof Collection || o instanceof CharSequence
        || o instanceof com.fasterxml.jackson.databind.node.TextNode);
}

Try / catch

try {
    int n = JsonPath.read(json, "$.items.length()");
} catch (JsonPathException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("length operation can not applied")) {
        n = 0; // treat undefined length as empty
    } else throw e;
}

Prevention

When it happens

Trigger: Evaluating a filter or length() function such as $.items.length() where the path resolves to null (missing property), a numeric/boolean/object node, or a non-TextNode scalar instead of an array/map/string/collection.

Common situations: Optional JSON fields missing in some documents so the path yields null; expecting a string but receiving a number node; calling length() on an object node instead of an array; defensive length checks in filters over heterogeneous documents.

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

Appendix: source

Thrown at json-path/src/main/java/com/jayway/jsonpath/spi/json/JacksonJsonNodeJsonProvider.java:225

        while (iter.hasNext()){
            keys.add(iter.next());
        }
        return keys;
    }

    @Override
    public int length(Object obj) {
        if (isArray(obj)) {
            return toJsonArray(obj).size();
        } else if (isMap(obj)) {
            return toJsonObject(obj).size();
        } else {
            if (obj instanceof TextNode) {
                TextNode element = (TextNode) obj;
                return element.size();
            }
        }
        throw new JsonPathException("length operation can not applied to " + (obj != null ? obj.getClass().getName()
                : "null"));
    }

    @Override
    public Iterable<?> toIterable(Object obj) {
        ArrayNode arr = toJsonArray(obj);
        Iterator<?> iterator = arr.iterator();
        return new Iterable<Object>() {
            @Override
            public Iterator<Object> iterator() {
                return new Iterator<Object>() {
                    @Override
                    public boolean hasNext() {
                        return iterator.hasNext();
                    }

                    @Override
                    public Object next() {

View on GitHub (pinned to 62a4c9f0f6)