{"record":{"id":"87ca8faa6a31603d","repo":"spring-projects/spring-ai","slug":"expected-a-list-value-for-s-expression-but-got","errorCode":null,"errorMessage":"Expected a List value for %s expression but got: %s","messagePattern":"Expected a List value for (.+?) expression but got: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStoreFilterExpressionEvaluator.java","lineNumber":217,"sourceCode":"\t\t}\n\t\tif (metaVal instanceof Comparable comparable && filterVal instanceof Comparable) {\n\t\t\ttry {\n\t\t\t\treturn comparable.compareTo(filterVal);\n\t\t\t}\n\t\t\tcatch (ClassCastException ex) {\n\t\t\t\tthrow new IllegalArgumentException(\"Cannot compare values of incompatible types %s and %s\"\n\t\t\t\t\t.formatted(metaVal.getClass().getName(), filterVal.getClass().getName()), ex);\n\t\t\t}\n\t\t}\n\t\tthrow new IllegalArgumentException(\"Cannot compare values of types %s and %s\"\n\t\t\t.formatted(metaVal.getClass().getName(), filterVal.getClass().getName()));\n\t}\n\n\tprivate List<?> asList(Object value, Filter.Expression expression) {\n\t\tif (value instanceof List<?> list) {\n\t\t\treturn list;\n\t\t}\n\t\tthrow new IllegalArgumentException(\n\t\t\t\t\"Expected a List value for %s expression but got: %s\".formatted(expression.type(), value));\n\t}\n\n}\n","sourceCodeStart":199,"sourceCodeEnd":222,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStoreFilterExpressionEvaluator.java#L199-L222","documentation":"IN and NIN expressions require the filter value to be a List. The evaluator's asList() throws IllegalArgumentException 'Expected a List value for %s expression but got: %s' when the right-hand operand of IN/NIN is a scalar value.","triggerScenarios":"Building new Filter.Expression(IN, new Filter.Key(\"country\"), new Filter.Value(\"US\")) — a scalar instead of List.of(\"US\", \"CA\"); or a text filter like \"country IN 'US'\" missing brackets.","commonSituations":"Porting SQL IN clauses with a single element and dropping the list; dynamic filters built from a collection that collapsed to a single element; typos in filter string syntax.","solutions":["Wrap the value in java.util.List: new Filter.Value(List.of(\"US\", \"CA\")).","In text filters, use bracketed list syntax: country IN ['US','CA'].","Guard collection-building code to always produce a List for IN/NIN operands, even for one element."],"exampleFix":"// before\nnew Filter.Expression(IN, new Filter.Key(\"country\"), new Filter.Value(\"US\"));\n// after\nnew Filter.Expression(IN, new Filter.Key(\"country\"), new Filter.Value(List.of(\"US\")));","handlingStrategy":"type-guard","validationCode":"boolean isListValued(Filter.Expression e) {\n    return e != null && e.right() instanceof Filter.Value v\n        && v.value() instanceof java.util.List<?>;\n}","typeGuard":"java.util.List<?> requireList(Filter.Value v) { return v.value() instanceof java.util.List<?> l ? l : java.util.List.of(); }","tryCatchPattern":"try {\n    vectorStore.similaritySearch(request);\n} catch (IllegalArgumentException ex) {\n    if (ex.getMessage().contains(\"Expected a List value\")) {\n        // wrap scalar in List.of(...) and rebuild\n    } else throw ex;\n}","preventionTips":["Always pass List operands for IN/NIN, even for single elements","Use bracketed list syntax in text filters: field IN ['a','b']"],"tags":["vector-store","filter-expression","in-operator","type-mismatch","spring-ai"],"backgroundTag":"invalid-argument-value","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}