spring-projects/spring-ai · error · RuntimeException
Not supported expression type:
Error message
Not supported expression type:
What it means
Neo4jVectorFilterExpressionConverter.getOperationSymbol switches over Filter.ExpressionType and throws a RuntimeException for any type it has no Cypher operator mapping for (default branch). This means a filter expression containing an expression type the Neo4j converter does not support was passed to the store for a similarity search with a filter.
Solutions
- Rewrite the filter expression using only supported types (AND, OR, EQ, NE, LT, LTE, GT, GTE, IN, NOT, NIN).
- Replace NIN with a negated IN via NOT to keep within supported symbols.
- Check the Spring AI version; upgrade or downgrade so converter and Filter.ExpressionType are in sync.
- Contribute/implement the missing case in getOperationSymbol if a new expression type is needed.
Example fix
// before
new Filter.Expression(ExpressionType.NOT, new In("tag", List.of("x")), null); // unhandled combination
// after
new Filter.Nin("tag", List.of("x")); // maps to the supported " NOT " symbol Defensive patterns
Strategy: validation
Validate before calling
static boolean isSupported(Filter.Expression exp) {
return switch (exp.type()) {
case AND, OR, EQ, NE, LT, LTE, GT, GTE, IN, NOT, NIN -> true;
default -> false;
};
}
// check recursively before similaritySearch Try / catch
try {
vectorStore.similaritySearch(request);
} catch (RuntimeException e) {
if (e.getMessage().startsWith("Not supported expression type")) {
// fall back to unfiltered search and post-filter
}
} Prevention
- Only build filters from the supported ExpressionType set for this converter
- Prefer builder methods (Filter.eq, Filter.in) over raw Expression constructors
- After Spring AI upgrades, re-check converter supported types
- Add a recursive filter-tree validator before hitting the store
When it happens
Trigger: Passing a SearchRequest whose filter expression uses an ExpressionType not mapped in the switch (e.g. NIN combined semantics, or a new type added to Filter in a newer Spring AI version) to Neo4jVectorStore.similaritySearch.
Common situations: Building complex filters programmatically with NOT/NIN and hitting an unhandled branch; upgrading Spring AI where new ExpressionType values were added but this converter was not updated; hand-rolled Filter.Expression trees containing unsupported nodes.
Related errors
- Cassandra uses a custom doValue(ColumnMetadata, Object…
- Expression type not supported for numeric fields
- Expression type not yet implemented. Patches welcome.
- Not supported expression type:
- Not supported expression type:
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/2aebd84d931d4ea1.
Report an issue: GitHub.
Appendix: source
Thrown at vector-stores/spring-ai-neo4j-store/src/main/java/org/springframework/ai/vectorstore/neo4j/filter/Neo4jVectorFilterExpressionConverter.java:64
context.append(this.getOperationSymbol(expression));
this.convertOperand(expression.right(), context);
}
}
private String getOperationSymbol(Expression exp) {
return switch (exp.type()) {
case AND -> " AND ";
case OR -> " OR ";
case EQ -> " = ";
case NE -> " <> ";
case LT -> " < ";
case LTE -> " <= ";
case GT -> " > ";
case GTE -> " >= ";
case IN -> " IN ";
case NOT, NIN -> " NOT ";
// you never know what the future might bring
default -> throw new RuntimeException("Not supported expression type: " + exp.type());
};
}
@Override
protected void doNot(Expression expression, StringBuilder context) {
Filter.ExpressionType expressionType = expression.type();
// should not happen, but better safe than sorry
if (expressionType != Filter.ExpressionType.NOT) {
throw new RuntimeException(
"Unsupported expression type %s. Only NOT is supported here".formatted(expressionType));
}
// explicitly prefix the embedded expression with NOT
context.append("NOT ").append(this.convertOperand(expression.left()));
}
@Override
protected void doKey(Key key, StringBuilder context) {View on GitHub (pinned to 98a7beda4f)