{"record":{"id":"a74c1829897031c4","repo":"spring-projects/spring-ai","slug":"not-supported-expression-type-expressiontype-a74c18","errorCode":null,"errorMessage":"Not supported expression type: {expressionType}","messagePattern":"Not supported expression type: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"vector-stores/spring-ai-milvus-store/src/main/java/org/springframework/ai/vectorstore/milvus/MilvusFilterExpressionConverter.java","lineNumber":67,"sourceCode":"\t\tAssert.state(exp.right() != null, \"expected expression.right to be non null\");\n\t\tthis.convertOperand(exp.left(), context);\n\t\tcontext.append(getOperationSymbol(exp));\n\t\tthis.convertOperand(exp.right(), context);\n\t}\n\n\tprivate String getOperationSymbol(Expression exp) {\n\t\treturn switch (exp.type()) {\n\t\t\tcase AND -> \" && \";\n\t\t\tcase OR -> \" || \";\n\t\t\tcase EQ -> \" == \";\n\t\t\tcase NE -> \" != \";\n\t\t\tcase LT -> \" < \";\n\t\t\tcase LTE -> \" <= \";\n\t\t\tcase GT -> \" > \";\n\t\t\tcase GTE -> \" >= \";\n\t\t\tcase IN -> \" in \";\n\t\t\tcase NIN -> \" not in \";\n\t\t\tdefault -> throw new RuntimeException(\"Not supported expression type:\" + exp.type());\n\t\t};\n\t}\n\n\t@Override\n\tprotected void doStartGroup(Group group, StringBuilder context) {\n\t\tcontext.append(\"(\");\n\t}\n\n\t@Override\n\tprotected void doEndGroup(Group group, StringBuilder context) {\n\t\tcontext.append(\")\");\n\t}\n\n\t@Override\n\tprotected void doKey(Key key, StringBuilder context) {\n\t\tvar identifier = key.key();\n\t\tcontext.append(this.metadataFieldName).append(\"[\");\n\t\temitJsonValue(identifier, context);","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/vector-stores/spring-ai-milvus-store/src/main/java/org/springframework/ai/vectorstore/milvus/MilvusFilterExpressionConverter.java#L49-L85","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nnew FilterExpressionBuilder().not(new FilterExpressionBuilder().eq(\"type\", \"x\")).build();\n// after\nnew FilterExpressionBuilder().ne(\"type\", \"x\").build();","handlingStrategy":"validation","validationCode":"private static final Set<Filter.ExpressionType> MILVUS_SUPPORTED =\n    Set.of(EQ, NE, LT, LTE, GT, GTE, IN, NIN, AND, OR);\nvoid assertMilvusSafe(Filter.Expression e) {\n    if (e.type() == Filter.ExpressionType.NOT)\n        throw new IllegalArgumentException(\"NOT unsupported on Milvus; invert condition\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    vectorStore.similaritySearch(request);\n} catch (RuntimeException e) {\n    if (String.valueOf(e.getMessage()).contains(\"Not supported expression type\")) {\n        // retry without the filter or with a rewritten expression\n    }\n}","preventionTips":["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."],"tags":["filter-expression","milvus","vector-store"],"backgroundTag":"unsupported-enum-value","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}