spring-projects/spring-ai · error · IllegalArgumentException
Expected a List value for
Error message
Expected a List value for %s expression but got: %s
What it means
S3VectorStore's filter expression evaluator requires the operand of IN/NIN expressions to be a JSON array (List). When the right-hand operand of such a filter expression is any other type (a scalar, a string, a map), asList throws this IllegalArgumentException because the S3 vector store filter syntax can only express set membership against a list.
Solutions
- Wrap the operand in a List: use List.of(value) or a collection when constructing IN/NIN expressions.
- Validate the operand type (value instanceof List) before calling similaritySearch/delete with an IN/NIN expression.
- If a scalar equality was intended, use Filter.ExpressionType.EQ instead of IN.
Example fix
// before
var expr = new Filter.Expression(IN, new Key("country"), new Value("USA"));
// after
var expr = new Filter.Expression(IN, new Key("country"), new Value(List.of("USA", "UK"))); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(operand instanceof List<?> list)) { throw new IllegalArgumentException("IN/NIN operand must be a List"); } Type guard
static boolean isListOperand(Object v) { return v instanceof List<?>; } Try / catch
try { vectorStore.similaritySearch(request); } catch (IllegalArgumentException e) { if (e.getMessage().contains("Expected a List")) { /* rebuild expression with List operand */ } else throw e; } Prevention
- Always wrap IN/NIN operands in List.of(...) or a collection
- Never use IN for scalar equality — use EQ
- Unit-test filter builders that generate set-membership expressions
When it happens
Trigger: Calling S3VectorStore similaritySearch (or delete by filter) with a Filter.Expression of type IN or NIN whose right operand is not a java.util.List, e.g. new Filter.Expression(IN, key, new Value("usa")) instead of List.of("usa").
Common situations: Building filter expressions programmatically or from user input and passing a single value where a collection is expected; forgetting that IN/NIN must always take a collection operand; parsing a JSON filter where the value was deserialized as a String.
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
- Cannot compare values of incompatible types
- Cannot compare values of types
- Cannot compare values of types
- Expected a List value for
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/6ac1efc07db327bc.
Report an issue: GitHub.
Appendix: source
Thrown at vector-stores/spring-ai-s3-vector-store/src/main/java/org/springframework/ai/vectorstore/s3/S3VectorStoreFilterExpressionEvaluator.java:154
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)