spring-projects/spring-ai · error · IllegalArgumentException
Cannot compare values of types %s and %s
Error message
Cannot compare values of types %s and %s
What it means
If either the metadata value or the filter value is not Comparable, the evaluator cannot perform an ordered/inequality comparison and throws IllegalArgumentException 'Cannot compare values of types'. Unlike error 504, this fires without attempting compareTo — the types simply do not support comparison.
Source
Thrown at spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStoreFilterExpressionEvaluator.java:209
if (filterVal == null) {
return 1;
}
if (metaVal instanceof Number n1 && filterVal instanceof Number n2) {
return Double.compare(n1.doubleValue(), n2.doubleValue());
}
if (Objects.equals(metaVal, filterVal)) {
return 0;
}
if (metaVal instanceof Comparable comparable && filterVal instanceof Comparable) {
try {
return comparable.compareTo(filterVal);
}
catch (ClassCastException ex) {
throw new IllegalArgumentException("Cannot compare values of incompatible types %s and %s"
.formatted(metaVal.getClass().getName(), filterVal.getClass().getName()), ex);
}
}
throw new IllegalArgumentException("Cannot compare values of types %s and %s"
.formatted(metaVal.getClass().getName(), filterVal.getClass().getName()));
}
private List<?> asList(Object value, Filter.Expression expression) {
if (value instanceof List<?> list) {
return list;
}
throw new IllegalArgumentException(
"Expected a List value for %s expression but got: %s".formatted(expression.type(), value));
}
}
View on GitHub (pinned to 98a7beda4f)
Solutions
- Ensure every document carries the metadata key used in filters, with a Comparable value (String, Number, Date).
- Use IN/NIN instead of scalar comparisons when metadata values are lists.
- Validate document metadata completeness at ingestion time.
Example fix
// before
// metadata missing 'year' on some docs; filter uses
new Filter.Expression(GTE, new Filter.Key("year"), new Filter.Value(2020));
// after
// ingest with metadata.put("year", 2020) fallback, or filter
new Filter.Expression(IN, new Filter.Key("year"), new Filter.Value(List.of(2020, 2021))); Defensive patterns
Strategy: validation
Validate before calling
boolean isComparable(Object v) {
return v instanceof Comparable<?>;
} Type guard
<T extends Comparable<T>> boolean canCompare(Object v, Class<T> type) { return type.isInstance(v); } Try / catch
try {
vectorStore.similaritySearch(request);
} catch (IllegalArgumentException ex) {
if (ex.getMessage().startsWith("Cannot compare values of types")) {
// ensure metadata key exists and is Comparable on all documents
} else throw ex;
} Prevention
- Require filter metadata keys on every ingested document
- Use IN/NIN for list-valued metadata instead of scalar comparisons
When it happens
Trigger: Filtering with GT/LT/GTE/LTE (or even EQ) on a metadata value that is null, a List, or a Map — types that are not Comparable.
Common situations: Metadata field missing from a document (null) while the filter uses inequality operators; filtering on list-valued metadata with a scalar comparison.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Cannot compare values of incompatible types %s and %s
- Expected a List value for %s expression but got: %s
- Cannot compare values of types %s and %s
- Expression of type %s requires a left operand
- Expression of type %s requires a right operand
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/30c95eb78e6b3d2e.
Report an issue: GitHub.