json-path/JsonPath · error · InvalidPathException

Could not parse criteria

Error message

Could not parse criteria

What it means

Criteria.parse(String) splits the criteria on single spaces and only understands exactly 1 token (bare path, EXISTS true) or 3 tokens (path operator value). Any other token count throws InvalidPathException 'Could not parse criteria'.

Source

Thrown at json-path/src/main/java/com/jayway/jsonpath/Criteria.java:479

     * Parse the provided criteria
     *
     * Deprecated use {@link Filter#parse(String)}
     *
     * @param criteria
     * @return a criteria
     */
    @Deprecated
    public static Criteria parse(String criteria) {
        if(criteria == null){
            throw new InvalidPathException("Criteria can not be null");
        }
        String[] split = criteria.trim().split(" ");
        if(split.length == 3){
            return create(split[0], split[1], split[2]);
        } else if(split.length == 1){
            return create(split[0], "EXISTS", "true");
        } else {
            throw new InvalidPathException("Could not parse criteria");
        }
    }

    /**
     * Creates a new criteria
     * @param left path to evaluate in criteria
     * @param operator operator
     * @param right expected value
     * @return a new Criteria
     */
    @Deprecated
    public static Criteria create(String left, String operator, String right) {
        Criteria criteria = new Criteria(ValueNode.toValueNode(left));
        criteria.criteriaType = RelationalOperator.fromString(operator);
        criteria.right = ValueNode.toValueNode(right);
        return criteria;
    }

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Ensure the string is exactly 'path operator value' or a bare path.
  2. Replace multiple spaces with single spaces before calling parse.
  3. Express compound logic via Filter.filter(where("$.a").eq(1).and("$.b").eq(2)) instead of a single string.
  4. Migrate to the programmatic Criteria/Filter API and abandon string parsing.

Example fix

// before
Criteria c = Criteria.parse("$.age  ==  30");
// after
Criteria c = Criteria.create("$.age", "==", "30");
// or
Filter f = Filter.filter(Criteria.where("$.age").is(30));
Defensive patterns

Strategy: validation

Validate before calling

String[] parts = criteria.trim().split("\\s+");
if (parts.length != 1 && parts.length != 3) throw new IllegalArgumentException("criteria must be 'path' or 'path op value': " + criteria);

Try / catch

try {
    Criteria c = Criteria.parse(criteria);
} catch (InvalidPathException e) {
    log.error("Unparseable criteria '{}': {}", criteria, e.getMessage());
    throw e;
}

Prevention

When it happens

Trigger: Criteria.parse("$.a == 1 extra") (4 tokens), Criteria.parse("$.a ==") (2 tokens), or criteria containing multi-space separators that produce empty tokens after split.

Common situations: Users writing filter strings with extra whitespace, compound conditions ('$.a == 1 and $.b == 2'), or operators containing spaces — formats parse() never supported.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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