json-path/JsonPath · error · InvalidPathException

Expected number node

Error message

Expected number node

What it means

ValueNode.asNumberNode() is the default implementation inherited by all non-numeric ValueNodes; only NumberNode can be converted. Filter evaluation code (e.g. evaluate() for size/numeric comparisons, expectedSize()) calls it when a numeric operand is required and throws InvalidPathException("Expected number node") if the operand is a string or other literal node.

Source

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

    public PatternNode asPatternNode() {
        throw new InvalidPathException("Expected regexp node");
    }

    public boolean isPathNode() {
        return false;
    }

    public PathNode asPathNode() {
        throw new InvalidPathException("Expected path node");
    }

    public boolean isNumberNode() {
        return false;
    }

    public NumberNode asNumberNode() {
        throw new InvalidPathException("Expected number node");
    }

    public boolean isStringNode() {
        return false;
    }

    public StringNode asStringNode() {
        throw new InvalidPathException("Expected string node");
    }

    public boolean isBooleanNode() {
        return false;
    }

    public BooleanNode asBooleanNode() {
        throw new InvalidPathException("Expected boolean node");
    }

View on GitHub (pinned to 62a4c9f0f6)

Solutions

  1. Write numeric operands unquoted so the parser produces a NumberNode (size 3, not size '3').
  2. Check isNumberNode() before calling asNumberNode() and convert string nodes explicitly (e.g. parse the string to a number and build a NumberNode).
  3. When building filter nodes programmatically, use ValueNode.NumberNode (or NumberNode.of(...)) for numeric values instead of string literals.
  4. Log the failing node's class at the call site to confirm which literal type was supplied.

Example fix

// before
ValueNode node = new ValueNode.StringNode("3");
node.asNumberNode(); // throws

// after
ValueNode node = new ValueNode.NumberNode(3);
if (node.isNumberNode()) {
    node.asNumberNode();
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Java: numeric operands in filters (e.g. size) must be unquoted integers
void validateNumericOperand(String filter) {
    java.util.regex.Matcher m = java.util.regex.Pattern.compile("size\\s+(\\S+)").matcher(filter);
    while (m.find()) {
        if (!m.group(1).matches("\\d+")) {
            throw new IllegalArgumentException("size requires an unquoted number, got: " + m.group(1));
        }
    }
}

Type guard

boolean asNumberSafe(ValueNode node) {
    return node.isNumberNode(); // only then call node.asNumberNode()
}

Try / catch

try {
    return node.asNumberNode();
} catch (InvalidPathException e) {
    if (e.getMessage().equals("Expected number node")) {
        throw new IllegalStateException("Expected a NumberNode, got " + node.getClass().getSimpleName(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Using the size operator with a non-numeric right operand (e.g. size '3' instead of size 3), or a numeric comparison whose operand the parser classified as a string/boolean node, so evaluate()/expectedSize() call asNumberNode() on the wrong node type.

Common situations: Quoting numbers in filters ([?(@.size == '3')]) and then using them where a numeric node is required; dynamically generated filters where sizes/counts are interpolated as strings; custom evaluation code assuming both operands are NumberNodes.

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