spring-projects/spring-ai · error · RuntimeException
Not supported expression type: {expressionType}
Error message
Not supported expression type: {expressionType} What it means
CouchbaseAiSearchFilterExpressionConverter.getOperationSymbol maps supported filter types to N1QL operator strings. Types outside GT, GTE, LT, LTE, IN, NIN (and the equality/comparison set handled before it) hit the default branch and throw this RuntimeException. It is called from doExpression during filter-to-N1QL conversion.
Source
Thrown at vector-stores/spring-ai-couchbase-store/src/main/java/org/springframework/ai/vectorstore/couchbase/CouchbaseAiSearchFilterExpressionConverter.java:57
}
else {
context.append("NULL");
}
}
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 NIN -> " NOT IN ";
default -> throw new RuntimeException("Not supported expression type: " + exp.type());
};
}
@Override
protected void doKey(Key key, StringBuilder context) {
context.append("metadata.");
var identifier = key.key();
// Couchbase N1QL/SQL++ uses backtick-quoted identifiers.
// Within backticks, the only character needing escaping is the backtick
// itself (doubled as ``).
context.append('`');
for (int i = 0; i < identifier.length(); i++) {
char c = identifier.charAt(i);
if (c == '`') {
context.append("``");
}
else {
context.append(c);View on GitHub (pinned to 98a7beda4f)
Solutions
- Rewrite NOT using De Morgan's laws with supported operators (NE, AND, OR).
- Replace CONTAINS/CONTAINS_KEY with EQ/IN where possible, or filter array metadata client-side after retrieval.
- Extend getOperationSymbol to emit N1QL for the missing operator (e.g. " NOT IN " patterns already exist for NIN).
Example fix
// before
new FilterExpressionBuilder().not(new FilterExpressionBuilder().eq("metadata.type", "tmp")).build();
// after
new FilterExpressionBuilder().ne("metadata.type", "tmp").build(); Defensive patterns
Strategy: validation
Validate before calling
Set<Filter.ExpressionType> N1QL_OK = Set.of(EQ, NE, GT, GTE, LT, LTE, IN, NIN, AND, OR);
void verify(Filter.Expression e) {
if (!N1QL_OK.contains(e.type())) throw new IllegalArgumentException("Unsupported for Couchbase: " + e.type());
if (e.left() instanceof Filter.Expression l) verify(l);
if (e.right() instanceof Filter.Expression r) verify(r);
} Type guard
boolean couchbaseSafe(Filter.Expression e) {
return e.type() != NOT && e.type() != CONTAINS && e.type() != CONTAINS_KEY;
} Try / catch
try {
vectorStore.similaritySearch(request);
} catch (RuntimeException e) {
if (e.getMessage().startsWith("Not supported expression type")) {
// rewrite filter without the unsupported operator and retry
}
} Prevention
- Replace NOT/CONTAINS filters with supported NE/IN/NIN combinations before querying Couchbase.
- Share an operator allow-list across vector store adapters to catch misuse early.
- Add unit tests that render every operator your app can emit through this converter.
When it happens
Trigger: Passing a filter expression with an unsupported type (e.g. NOT, CONTAINS) to a Couchbase vector store search or delete; the N1QL converter has no operator symbol for it.
Common situations: Filters parsed from text with negation operators; reusing filter DSLs from other vector stores; metadata array searches using CONTAINS.
Related errors
- Expression type %s not yet implemented. Patches welcome.
- Unexpected value: {expressionType}
- Failed to delete documents by filter
- Not supported expression type: {expressionType}
- Not supported expression type: {expressionType}
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/d65d7cb3944dfac4.
Report an issue: GitHub.