spring-projects/spring-ai · error · IllegalArgumentException

Cannot compare values of incompatible types %s and %s

Error message

Cannot compare values of incompatible types %s and %s

What it means

compare() throws this when both metadata and filter values are Comparable but compareTo() raises ClassCastException, e.g. comparing a String metadata value against a numeric filter value. It is the evaluator's way of surfacing mixed-type comparisons during post-filtering of ListVectors metadata.

Source

Thrown at vector-stores/spring-ai-s3-vector-store/src/main/java/org/springframework/ai/vectorstore/s3/S3VectorStoreFilterExpressionEvaluator.java:142

			return -1;
		}
		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 {
				@SuppressWarnings("unchecked")
				int result = comparable.compareTo(filterVal);
				return result;
			}
			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

  1. Match the filter literal type to the stored metadata type (e.g. Filter.Value("30") for String metadata).
  2. Fix the ingestion pipeline so the field is always written with a consistent type across documents.
  3. Normalize values before filtering: convert metadata or filter values to a common type (Number or ISO date String).
  4. For dates, remember the evaluator formats Date filter values as yyyy-MM-dd'T'HH:mm:ss'Z' strings — compare against same-format string metadata, or pre-convert.

Example fix

// before
new Filter.Expression(Filter.ExpressionType.GT, new Filter.Key("age"), new Filter.Value(30)) // metadata age is "30" String
// after
new Filter.Expression(Filter.ExpressionType.GT, new Filter.Key("age"), new Filter.Value("30"))
Defensive patterns

Strategy: validation

Validate before calling

static void assertSameScalarType(Object metadataSample, Object filterValue) {
  if (metadataSample != null && !metadataSample.getClass().isInstance(filterValue)
      && !(metadataSample instanceof Number && filterValue instanceof Number))
    throw new IllegalStateException("Filter type " + filterValue.getClass() + " differs from metadata type " + metadataSample.getClass());
}

Type guard

static boolean comparableTypes(Object a, Object b) { return (a instanceof Number && b instanceof Number) || (a != null && b != null && a.getClass().equals(b.getClass())); }

Try / catch

try { store.similaritySearch(req); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Cannot compare values of incompatible types")) { /* rebuild filter with matching literal type */ } }

Prevention

When it happens

Trigger: Filtering a field whose stored metadata type differs from the filter literal type — e.g. metadata stores age as "30" (String) but the filter uses new Filter.Value(30), or a Date-formatted string compared to a Date/Number — during S3VectorStore similaritySearch.

Common situations: Metadata written by earlier ingestion code with a different type (String vs number vs boolean); JSON round-trips that turned numbers into strings; comparing numbers to date strings; locale-specific comparable types.

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


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