json-path/JsonPath · error · InvalidPathException

Expected <null> value

Error message

Expected <null> value

What it means

Thrown by FilterCompiler.readNullLiteral when a token started as a potential null literal (beginning with 'n') does not spell exactly 'null'. readLiteral dispatches to this method on a candidate token, and if the characters do not match the reserved word, the compiler has no value node to produce and raises 'Expected <null> value'. It indicates a misspelled or partial null keyword inside the filter predicate.

Source

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

            }
        }

        CharSequence operator = filter.subSequence(begin, filter.position());
        logger.trace("Operator from {} to {} -> [{}]", begin, filter.position()-1, operator);
        return RelationalOperator.fromString(operator.toString());
    }

    private NullNode readNullLiteral() {
        int begin = filter.position();
        if(filter.currentChar() == NULL && filter.inBounds(filter.position() + 3)){
            CharSequence nullValue = filter.subSequence(filter.position(), filter.position() + 4);
            if("null".equals(nullValue.toString())){
                logger.trace("NullLiteral from {} to {} -> [{}]", begin, filter.position()+3, nullValue);
                filter.incrementPosition(nullValue.length());
                return ValueNode.createNullNode();
            }
        }
        throw new InvalidPathException("Expected <null> value");
    }

    private JsonNode readJsonLiteral(){
        int begin = filter.position();

        char openChar = filter.currentChar();

        assert openChar == OPEN_ARRAY || openChar == OPEN_OBJECT;

        char closeChar = openChar == OPEN_ARRAY ? CLOSE_ARRAY : CLOSE_OBJECT;

        int closingIndex = filter.indexOfMatchingCloseChar(filter.position(), openChar, closeChar, true, false);
        if (closingIndex == -1) {
            throw new InvalidPathException("String not closed. Expected " + SINGLE_QUOTE + " in " + filter);
        } else {
            filter.setPosition(closingIndex + 1);
        }
        CharSequence json = filter.subSequence(begin, filter.position());

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Spell the keyword exactly as lowercase 'null': "$[?(@.a == null)]"
  2. If the value is not meant as null, quote it as a string literal: "$[?(@.a == 'null')]"
  3. Remember JsonPath literals are case-sensitive — 'Null' and 'NULL' are not accepted
  4. For existence checks on missing fields, use an existence-style predicate instead of a misspelled null keyword

Example fix

// before
String path = "$[?(@.middleName == Null)]";
// after
String path = "$[?(@.middleName == null)]";
Defensive patterns

Strategy: type-guard

Validate before calling

// Normalize casing/keyword typos before compiling
String normalizeNull(String predicate) {
    return predicate.replaceAll("(?<=\\s|=|!)\\s*(Null|NULL|None|nil)\\b", "null");
}
// normalizeNull("$[?(@.a == None)]") -> "$[?(@.a == null)]"

Type guard

static boolean usesCorrectNullKeyword(String filter) {
    return !java.util.regex.Pattern.compile("(Null|NULL|None|nil|nul)").matcher(filter).find();
}

Try / catch

try {
    Object v = JsonPath.parse(json).read(path);
} catch (InvalidPathException e) {
    if (e.getMessage().contains("Expected <null> value")) {
        throw new IllegalArgumentException("Use lowercase 'null' literal in filter: " + path);
    }
    throw e;
}

Prevention

When it happens

Trigger: A filter predicate containing a near-null token where a literal is expected: "$[?(@.a == nul)]", "$[?(@.a == Null)]" (case-sensitive), "$[?(@.a == none)]"; triggered via Filter.compile or JsonPath.parse(...).read(path) on an inline filter.

Common situations: Language-habit casing ('Null'/'NULL' from SQL or C#, Python's 'None'); truncated strings from templating; trying to compare against a value that starts with 'n' without quoting it as a string.

Related errors


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