spring-projects/spring-ai · error · IllegalArgumentException
Numeric value must be a Number
Error message
Numeric value must be a Number
What it means
In RedisFilterExpressionConverter.inclusive(), the boundary value of a numeric filter expression must be an instance of java.lang.Number. If value.value() is a String, Boolean or any other object, the converter throws this IllegalArgumentException because it cannot build a Redis NumericBoundary from it. This guards the numeric range construction for EQ/GTE/LTE-style boundaries.
Source
Thrown at vector-stores/spring-ai-redis-store/src/main/java/org/springframework/ai/vectorstore/redis/RedisFilterExpressionConverter.java:204
MessageFormat.format("Tag operand {0} not supported", expression.type()));
};
}
private Numeric numeric(Expression expression, Value value) {
return switch (expression.type()) {
case EQ -> new Numeric(inclusive(value), inclusive(value));
case GT -> new Numeric(exclusive(value), NumericBoundary.POSITIVE_INFINITY);
case GTE -> new Numeric(inclusive(value), NumericBoundary.POSITIVE_INFINITY);
case LT -> new Numeric(NumericBoundary.NEGATIVE_INFINITY, exclusive(value));
case LTE -> new Numeric(NumericBoundary.NEGATIVE_INFINITY, inclusive(value));
default -> throw new UnsupportedOperationException(
MessageFormat.format("Expression type {0} not supported for numeric fields", expression.type()));
};
}
private NumericBoundary inclusive(Value value) {
if (!(value.value() instanceof Number)) {
throw new IllegalArgumentException("Numeric value must be a Number");
}
return new NumericBoundary(value.value(), false);
}
private NumericBoundary exclusive(Value value) {
if (!(value.value() instanceof Number)) {
throw new IllegalArgumentException("Numeric value must be a Number");
}
return new NumericBoundary(value.value(), true);
}
@Override
protected void doSingleValue(Object value, StringBuilder context) {
emitJsonValue(value, context);
}
record Numeric(NumericBoundary lower, NumericBoundary upper) {
View on GitHub (pinned to 98a7beda4f)
Solutions
- Pass a Java Number type (Integer, Long, Double, Float) as the filter value for numeric fields
- Parse String input explicitly before building the expression, e.g. Integer.parseInt(value)
- Verify the metadata field type at write time so numeric fields always hold numeric values
Example fix
// before
Filter.Expression expr = b.eq("year", "2024").build();
// after
Filter.Expression expr = b.eq("year", Integer.parseInt("2024")).build(); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(rawValue instanceof Number)) throw new IllegalArgumentException("Numeric filter value must be a Number: " + rawValue); Type guard
static boolean isNumericValue(Object v) { return v instanceof Number; } Try / catch
try { store.similaritySearch(req); } catch (IllegalArgumentException e) { if (e.getMessage().contains("must be a Number")) { /* fix filter value type */ } } Prevention
- Use typed builder values (Integer/Double) not Strings
- Parse user input to numbers before building filters
- Keep metadata field types consistent at write time
When it happens
Trigger: Passing a non-numeric value in a filter expression against a numeric field, e.g. eq("year", "2024") (String instead of int), or a metadata value that was stored/typed as a String but used in a numeric comparison.
Common situations: Reading filter values from JSON/HTTP request parameters where everything arrives as a String; metadata written with String values then used in numeric filters; auto-boxing assumptions after refactoring a field from numeric to text.
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
- Cannot compare values of incompatible types %s and %s
- Cannot compare values of types %s and %s
- Expected a List value for %s expression but got: %s
- Not allowed filter identifier name:
- Field type {0} not supported
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/3aa73867cca97a68.
Report an issue: GitHub.