spring-projects/spring-ai · error · UnsupportedOperationException
Expression type {0} not supported for numeric fields
Error message
Expression type {0} not supported for numeric fields What it means
RedisFilterExpressionConverter.numeric() only supports the comparison operators EQ, GT, GTE, LT and LTE when translating a Filter.Expression into a Redis numeric range. Any other expression type (e.g. NIN, AND, OR, IN applied to a numeric field) hits the default branch and throws this UnsupportedOperationException. It signals that the filter expression uses an operator the Redis numeric-range mapping cannot express.
Source
Thrown at vector-stores/spring-ai-redis-store/src/main/java/org/springframework/ai/vectorstore/redis/RedisFilterExpressionConverter.java:197
}
private String tagValueDelimiter(Expression expression) {
return switch (expression.type()) {
case IN -> " | ";
case EQ -> " ";
default -> throw new UnsupportedOperationException(
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);
}
View on GitHub (pinned to 98a7beda4f)
Solutions
- Use only supported operators (EQ, GT, GTE, LT, LTE) for numeric fields in your filter expression
- Express the negation differently, e.g. combine GT and LT ranges instead of NE/NIN
- If you control the code, extend RedisFilterExpressionConverter to map the missing expression type to an equivalent Redis range or tag set
Example fix
// before
Filter.Expression expr = new FilterExpressionBuilder().nin("year", 2020, 2021).build();
// after
Filter.Expression expr = new FilterExpressionBuilder().and(
new FilterExpressionBuilder().lt("year", 2020).build(),
new FilterExpressionBuilder().gt("year", 2021).build()); Defensive patterns
Strategy: validation
Validate before calling
java.util.Set<Filter.ExpressionType> SUPPORTED = Set.of(Filter.ExpressionType.EQ, Filter.ExpressionType.GT, Filter.ExpressionType.GTE, Filter.ExpressionType.LT, Filter.ExpressionType.LTE);
if (!SUPPORTED.contains(expr.type())) throw new IllegalArgumentException("Unsupported numeric operator: " + expr.type()); Try / catch
try { store.similaritySearch(req); } catch (UnsupportedOperationException e) { log.warn("Filter operator not supported for numeric fields", e); } Prevention
- Restrict numeric filters to EQ/GT/GTE/LT/LTE
- Replace NE/NIN with combined range or negated-tag expressions
- Unit-test filter expressions against the Redis converter
When it happens
Trigger: Calling RedisVectorStore.similaritySearch() with a FilterExpressionBuilder expression whose type is not one of EQ/GT/GTE/LT/LTE on a numeric metadata field, e.g. a NIN or NE expression, or a top-level boolean expression passed where numeric() is invoked.
Common situations: Building filters with FilterExpressionBuilder.ne() or .nin() on a numeric field like 'year' or 'price'; porting filters written for another vector store that supports more operators; framework upgrades where new expression types appear but the converter was not extended.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Expression type %s not yet implemented. Patches welcome.
- Unexpected value: {expressionType}
- Not supported expression type: {expressionType}
- Not supported expression type: {expressionType}
- Not supported expression type: {expressionType}
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/8737bc5f2931254b.
Report an issue: GitHub.