spring-projects/spring-ai · error · RuntimeException
Not supported expression type: {expressionType}
Error message
Not supported expression type: {expressionType} What it means
MilvusFilterExpressionConverter.getOperationSymbol maps Filter.ExpressionType values to Milvus boolean-expression operator strings. If doExpression encounters an expression type not covered by the switch (notably NOT is absent from the Milvus switch), it throws this RuntimeException. It means the filter expression uses an operator the Milvus converter cannot translate.
Source
Thrown at vector-stores/spring-ai-milvus-store/src/main/java/org/springframework/ai/vectorstore/milvus/MilvusFilterExpressionConverter.java:67
Assert.state(exp.right() != null, "expected expression.right to be non null");
this.convertOperand(exp.left(), context);
context.append(getOperationSymbol(exp));
this.convertOperand(exp.right(), context);
}
private String getOperationSymbol(Expression exp) {
return switch (exp.type()) {
case AND -> " && ";
case OR -> " || ";
case EQ -> " == ";
case NE -> " != ";
case LT -> " < ";
case LTE -> " <= ";
case GT -> " > ";
case GTE -> " >= ";
case IN -> " in ";
case NIN -> " not in ";
default -> throw new RuntimeException("Not supported expression type:" + exp.type());
};
}
@Override
protected void doStartGroup(Group group, StringBuilder context) {
context.append("(");
}
@Override
protected void doEndGroup(Group group, StringBuilder context) {
context.append(")");
}
@Override
protected void doKey(Key key, StringBuilder context) {
var identifier = key.key();
context.append(this.metadataFieldName).append("[");
emitJsonValue(identifier, context);View on GitHub (pinned to 98a7beda4f)
Solutions
- Rewrite the filter without NOT — e.g. invert the inner comparison (eq -> ne) instead of wrapping in not().
- Use only operators the Milvus converter supports: EQ, NE, LT, LTE, GT, GTE, IN, NIN, AND, OR, and grouping.
- Align spring-ai core and milvus-store versions so new expression types are handled.
- If forking, add the missing case (e.g. NOT via !(...) in Milvus boolean syntax) to getOperationSymbol.
Example fix
// before
new FilterExpressionBuilder().not(new FilterExpressionBuilder().eq("type", "x")).build();
// after
new FilterExpressionBuilder().ne("type", "x").build(); Defensive patterns
Strategy: validation
Validate before calling
private static final Set<Filter.ExpressionType> MILVUS_SUPPORTED =
Set.of(EQ, NE, LT, LTE, GT, GTE, IN, NIN, AND, OR);
void assertMilvusSafe(Filter.Expression e) {
if (e.type() == Filter.ExpressionType.NOT)
throw new IllegalArgumentException("NOT unsupported on Milvus; invert condition");
} Try / catch
try {
vectorStore.similaritySearch(request);
} catch (RuntimeException e) {
if (String.valueOf(e.getMessage()).contains("Not supported expression type")) {
// retry without the filter or with a rewritten expression
}
} Prevention
- Never use FilterExpressionType.NOT with the Milvus store; use ne() or invert operands.
- Keep spring-ai core and milvus-store module versions aligned.
- Share filter-building code per-store rather than assuming portability.
- Cover each filter expression in unit tests against Milvus.
When it happens
Trigger: Calling MilvusVectorStore.similaritySearch with a SearchRequest whose FilterExpression uses an unsupported type (e.g. FilterExpressionType.NOT, since the Milvus switch has no NOT case), or a new expression type introduced in a newer spring-ai core.
Common situations: Portable filter code shared across vector stores that uses NOT on Milvus; upgrading spring-ai core ahead of the Milvus store module; programmatic filter builders emitting unhandled operators.
Related errors
- Failed to delete documents by filter:
- Failed to delete documents by filter
- Unsupported operand type:
- Expression of type %s requires a left operand
- Expression of type %s requires a right operand
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/a74c1829897031c4.
Report an issue: GitHub.