json-path/JsonPath · error · PathNotFoundException

The path is null

Error message

The path  is null

What it means

checkArrayModel() on ArrayPathToken is called when evaluating array index/slice tokens. If the model at currentPath is null (the parent path did not resolve), the token throws PathNotFoundException('The path <currentPath> is null') — unless upstream is indefinite (wildcards/filters, where missing branches are tolerated) or Option.SUPPRESS_EXCEPTIONS is set.

Source

Thrown at json-path/src/main/java/com/jayway/jsonpath/internal/path/ArrayPathToken.java:40

public abstract class ArrayPathToken extends PathToken {

    /**
     * Check if model is non-null and array.
     * @param currentPath
     * @param model
     * @param ctx
     * @return false if current evaluation call must be skipped, true otherwise
     * @throws PathNotFoundException if model is null and evaluation must be interrupted
     * @throws InvalidPathException if model is not an array and evaluation must be interrupted
     */
    protected boolean checkArrayModel(String currentPath, Object model, EvaluationContextImpl ctx) {
        if (model == null){
            if (!isUpstreamDefinite()
                    || ctx.options().contains(Option.SUPPRESS_EXCEPTIONS)) {
                return false;
            } else {
                throw new PathNotFoundException("The path " + currentPath + " is null");
            }
        }
        if (!ctx.jsonProvider().isArray(model)) {
            if (!isUpstreamDefinite()
                    || ctx.options().contains(Option.SUPPRESS_EXCEPTIONS)) {
                return false;
            } else {
                throw new PathNotFoundException(format("Filter: %s can only be applied to arrays. Current context is: %s", toString(), model));
            }
        }
        return true;
    }
}

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Add Option.SUPPRESS_EXCEPTIONS to the Configuration and handle the returned null/absent value.
  2. Validate the document shape (e.g. a null check on the parent) before running the indexed path.
  3. Use JsonPath.read(path, returnType, new Configuration.Defaults...) with a default or catch PathNotFoundException.
  4. Fix the path or the fixture so the intermediate path exists.

Example fix

// before
List<Object> first = JsonPath.read(json, "$.orders.items[0]"); // orders missing -> PathNotFoundException
// after
Configuration cfg = Configuration.builder().options(Option.SUPPRESS_EXCEPTIONS).build();
List<Object> first = JsonPath.using(cfg).read(json, "$.orders.items[0]");
Defensive patterns

Strategy: try-catch

Validate before calling

Object parent = JsonPath.read(json, "$.orders");
if (parent == null) return Collections.emptyList(); // skip indexed read

Try / catch

try {
    return JsonPath.read(json, "$.orders.items[0]");
} catch (PathNotFoundException e) {
    if (e.getMessage().contains("is null")) return Collections.emptyList(); // parent missing
    throw e;
}

Prevention

When it happens

Trigger: Reading a path like $.a.b[0] where $.a.b does not exist in the document, via JsonPath.read() without SUPPRESS_EXCEPTIONS and with a definite (non-wildcard) upstream path.

Common situations: Assuming optional JSON fields exist (documents from different API versions), reading indexes into arrays behind missing parents, deserialized/partial documents, or tests using minimal fixtures.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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