spring-projects/spring-ai · error · RuntimeException

Not supported expression type: {expressionType}

Error message

Not supported expression type: {expressionType}

What it means

ElasticsearchAiSearchFilterExpressionConverter.getOperationSymbol throws RuntimeException when it encounters a Filter.Expression type it has no SQL-like operator mapping for. Only IN, EQ, NE, LT, LTE, GT, GTE, NIN are supported; grouping with AND/OR is handled elsewhere, so anything else (unsupported future types) hits the default branch.

Source

Thrown at vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchAiSearchFilterExpressionConverter.java:97

	}

	@Override
	protected void doAddValueRangeSpitter(Filter.Value listValue, StringBuilder context) {
		context.append(" OR ");
	}

	private String getOperationSymbol(Expression exp) {
		return switch (exp.type()) {
			case AND -> " AND ";
			case OR -> " OR ";
			case EQ, IN -> "";
			case NE -> " NOT ";
			case LT -> "<";
			case LTE -> "<=";
			case GT -> ">";
			case GTE -> ">=";
			case NIN -> "NOT ";
			default -> throw new RuntimeException("Not supported expression type: " + exp.type());
		};
	}

	@Override
	public void doKey(Key key, StringBuilder context) {
		var fieldPath = "metadata." + key.key().trim();
		emitLuceneString(fieldPath, context);
		context.append(':');
	}

	@Override
	protected void doValue(Filter.Value filterValue, StringBuilder context) {
		if (filterValue.value() instanceof List list) {
			int c = 0;
			for (Object v : list) {
				this.doSingleValue(normalizeDateString(v), context);
				if (c++ < list.size() - 1) {
					this.doAddValueRangeSpitter(filterValue, context);

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Restrict filter expressions to IN, EQ, NE, LT, LTE, GT, GTE, NIN and AND/OR grouping
  2. Upgrade spring-ai-elasticsearch-store so converter and Filter API versions match
  3. Extend the converter by subclassing and overriding getOperationSymbol if a custom type is required

Example fix

// before: unsupported custom expression type
Expression expr = new Filter.Expression(MyCustomType.MATCHES, key, value);
// after: use supported types
Expression expr = new Filter.Expression(ExpressionType.EQ, key, value);
Defensive patterns

Strategy: validation

Validate before calling

private static final Set<ExpressionType> SUPPORTED = Set.of(IN, EQ, NE, LT, LTE, GT, GTE, NIN);
void validate(Filter.Expression e) { if (!SUPPORTED.contains(e.type())) throw new IllegalArgumentException("Unsupported type: " + e.type()); }

Try / catch

try {
    vectorStore.delete(filterExpression);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("Not supported expression type")) {
        throw new IllegalArgumentException("Simplify the filter to supported operators", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Passing a Filter.Expression whose ExpressionType is not in the supported set (e.g. an unsupported/extension type) into vectorStore.delete(Filter.Expression) or similaritySearch with a filter that gets converted to Elasticsearch query-string syntax.

Common situations: Building custom expression types, using a newer Spring AI Filter API with an older converter, or programmatically constructing expressions with types the converter never learned to serialize.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/493f3100a8a469a7. Report an issue: GitHub.