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
- Write numeric operands unquoted so the parser produces a NumberNode (size 3, not size '3').
- Check isNumberNode() before calling asNumberNode() and convert string nodes explicitly (e.g. parse the string to a number and build a NumberNode).
- When building filter nodes programmatically, use ValueNode.NumberNode (or NumberNode.of(...)) for numeric values instead of string literals.
- 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
- Write numeric filter operands unquoted: size 3, not size '3'.
- Check isNumberNode() before asNumberNode().
- Convert user-supplied numbers explicitly with NumberNode instead of string interpolation.
- Validate generated filters with a parse test before evaluation.
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
- Expected regexp node
- Expected path node
- Failed to evaluate exists expression
- Could not find matching close quote for %s when parsing : %s
- Could not find matching close for %s when parsing regex in :
AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11).
Data as JSON: /api/errors/278f75622add60a6.
Report an issue: GitHub.