spring-projects/spring-ai · error · RuntimeException
Not supported expression type: {expressionType}
Error message
Not supported expression type: {expressionType} What it means
ElasticsearchAiSearchFilterExpressionConverter.getOperationSymbol throws RuntimeException when it encounters a Filter.Expression type it has no SQL-like operator mapping for. Only IN, EQ, NE, LT, LTE, GT, GTE, NIN are supported; grouping with AND/OR is handled elsewhere, so anything else (unsupported future types) hits the default branch.
Source
Thrown at vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchAiSearchFilterExpressionConverter.java:97
}
@Override
protected void doAddValueRangeSpitter(Filter.Value listValue, StringBuilder context) {
context.append(" OR ");
}
private String getOperationSymbol(Expression exp) {
return switch (exp.type()) {
case AND -> " AND ";
case OR -> " OR ";
case EQ, IN -> "";
case NE -> " NOT ";
case LT -> "<";
case LTE -> "<=";
case GT -> ">";
case GTE -> ">=";
case NIN -> "NOT ";
default -> throw new RuntimeException("Not supported expression type: " + exp.type());
};
}
@Override
public void doKey(Key key, StringBuilder context) {
var fieldPath = "metadata." + key.key().trim();
emitLuceneString(fieldPath, context);
context.append(':');
}
@Override
protected void doValue(Filter.Value filterValue, StringBuilder context) {
if (filterValue.value() instanceof List list) {
int c = 0;
for (Object v : list) {
this.doSingleValue(normalizeDateString(v), context);
if (c++ < list.size() - 1) {
this.doAddValueRangeSpitter(filterValue, context);View on GitHub (pinned to 98a7beda4f)
Solutions
- Restrict filter expressions to IN, EQ, NE, LT, LTE, GT, GTE, NIN and AND/OR grouping
- Upgrade spring-ai-elasticsearch-store so converter and Filter API versions match
- Extend the converter by subclassing and overriding getOperationSymbol if a custom type is required
Example fix
// before: unsupported custom expression type Expression expr = new Filter.Expression(MyCustomType.MATCHES, key, value); // after: use supported types Expression expr = new Filter.Expression(ExpressionType.EQ, key, value);
Defensive patterns
Strategy: validation
Validate before calling
private static final Set<ExpressionType> SUPPORTED = Set.of(IN, EQ, NE, LT, LTE, GT, GTE, NIN);
void validate(Filter.Expression e) { if (!SUPPORTED.contains(e.type())) throw new IllegalArgumentException("Unsupported type: " + e.type()); } Try / catch
try {
vectorStore.delete(filterExpression);
} catch (RuntimeException e) {
if (e.getMessage().startsWith("Not supported expression type")) {
throw new IllegalArgumentException("Simplify the filter to supported operators", e);
}
throw e;
} Prevention
- Only build filters with IN, EQ, NE, LT, LTE, GT, GTE, NIN and AND/OR
- Keep Spring AI core and store module versions aligned
- Unit-test custom converters against all ExpressionType values
When it happens
Trigger: Passing a Filter.Expression whose ExpressionType is not in the supported set (e.g. an unsupported/extension type) into vectorStore.delete(Filter.Expression) or similaritySearch with a filter that gets converted to Elasticsearch query-string syntax.
Common situations: Building custom expression types, using a newer Spring AI Filter API with an older converter, or programmatically constructing expressions with types the converter never learned to serialize.
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}
- Expression type {0} not supported for numeric fields
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/493f3100a8a469a7.
Report an issue: GitHub.