{"record":{"id":"5aed7cc9935829ae","repo":"spring-projects/spring-ai","slug":"not-supported-expression-type-5aed7c","errorCode":null,"errorMessage":"Not supported expression type: ","messagePattern":"Not supported expression type: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"vector-stores/spring-ai-pgvector-store/src/main/java/org/springframework/ai/vectorstore/pgvector/PgVectorFilterExpressionConverter.java","lineNumber":112,"sourceCode":"\t}\n\n\tprivate void handleNotIn(Expression expression, StringBuilder context) {\n\t\tcontext.append(\"!(\");\n\t\tconvertToConditions(expression, context);\n\t\tcontext.append(\")\");\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\tdefault -> throw new RuntimeException(\"Not supported expression type: \" + exp.type());\n\t\t};\n\t}\n\n\t@Override\n\tpublic String convertExpression(Expression expression) {\n\t\tString jsonPath = super.convertExpression(expression);\n\t\treturn quoteIdentifier(this.metadataColumn) + \"::jsonb @@ '\" + jsonPath + \"'::jsonpath\";\n\t}\n\n\t/**\n\t * Quote a SQL identifier using double quotes (PostgreSQL/SQL standard) only if\n\t * needed. Simple identifiers (alphanumeric starting with letter/underscore) are\n\t * returned unquoted to preserve PostgreSQL's case-insensitive behavior. Identifiers\n\t * containing special characters are quoted with internal double quotes escaped by\n\t * doubling.\n\t */\n\tprivate static String quoteIdentifier(String identifier) {\n\t\tif (identifier.matches(\"^[A-Za-z_][A-Za-z0-9_]*$\")) {","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/vector-stores/spring-ai-pgvector-store/src/main/java/org/springframework/ai/vectorstore/pgvector/PgVectorFilterExpressionConverter.java#L94-L130","documentation":"getOperationSymbol maps only comparison operator types (EQ, NE, LT, LTE, GT, GTE) to SQL symbols; any other ExpressionType reaching doExpression (e.g. AND/OR groups, IN operators) hits the default branch and throws a RuntimeException. The PGVector converter handles IN via convertToConditions and boolean groups elsewhere, so this indicates an expression was dispatched to the wrong handler.","triggerScenarios":"Calling convertExpression on a Filter.Expression whose type is not one of EQ/NE/LT/LTE/GT/GTE — e.g. passing an IN/AND/OR node into the single-comparison code path, or a newly added enum type not yet supported by this converter.","commonSituations":"Custom filter-building code that mislabels expression types; using a filter DSL feature (e.g. nested groups) routed through doExpression after a library upgrade changed enum dispatch; copy-pasted converter code missing new enum cases.","solutions":["Ensure only EQ/NE/LT/LTE/GT/GTE expressions reach the comparison path; route IN/NOTIN through convertToConditions and AND/OR through the group handler.","Inspect exp.type() in the message and rebuild the filter with a supported operator.","Upgrade spring-ai to a version where the converter supports the expression type you use."],"exampleFix":"// before\nnew Expression(ExpressionType.AND, left, right) routed into doExpression comparison path\n// after\nnew Group(new Expression(ExpressionType.AND, left, right)) so it is handled by the group branch","handlingStrategy":"type-guard","validationCode":"Set<ExpressionType> supported = Set.of(EQ, NE, LT, LTE, GT, GTE);\nif (expr instanceof Filter.Expression fe && !supported.contains(fe.type())) {\n    throw new IllegalArgumentException(\"Unsupported type for comparison path: \" + fe.type());\n}","typeGuard":"static boolean isSimpleComparison(Expression e) {\n    return e instanceof Filter.Expression fe\n        && EnumSet.of(EQ, NE, LT, LTE, GT, GTE).contains(fe.type());\n}","tryCatchPattern":"try {\n    return converter.convertExpression(expr);\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Not supported expression type\")) {\n        throw new UnsupportedOperationException(e);\n    }\n    throw e;\n}","preventionTips":["Build filters with the Filter DSL instead of raw Expression nodes.","Route AND/OR through Group nodes so the converter's group branch handles them.","Keep spring-ai upgraded so new expression types are supported."],"tags":["filter-expression","pgvector","unsupported-type"],"backgroundTag":"unsupported-operation","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}