spring-projects/spring-ai · error · IllegalArgumentException
Expected Value but got:
Error message
Expected Value but got:
What it means
extractValue narrows a Filter.Operand to a Filter.Value and returns its raw Java value when building comparison operands for Bedrock RetrievalFilter documents. If the operand is an Expression rather than a Value (a key or sub-expression on the value side of a comparison), it throws an IllegalArgumentException naming the actual class.
Source
Thrown at vector-stores/spring-ai-bedrock-knowledgebase-store/src/main/java/org/springframework/ai/vectorstore/bedrockknowledgebase/BedrockKnowledgeBaseFilterExpressionConverter.java:147
return RetrievalFilter.builder().notIn(attr).build();
}
private FilterAttribute createFilterAttribute(final String key, final Object value) {
return FilterAttribute.builder().key(key).value(toDocument(value)).build();
}
private Expression asExpression(final Filter.Operand operand) {
if (operand instanceof Expression expr) {
return expr;
}
throw new IllegalArgumentException("Expected Expression but got: " + operand.getClass());
}
private Object extractValue(final Filter.Operand operand) {
if (operand instanceof Value value) {
return value.value();
}
throw new IllegalArgumentException("Expected Value but got: " + operand.getClass());
}
private List<?> extractListValue(final Filter.Operand operand) {
Object value = extractValue(operand);
if (value instanceof List) {
return (List<?>) value;
}
throw new IllegalArgumentException("Expected List for IN/NIN but got: " + value.getClass());
}
private Document toDocument(final Object value) {
if (value instanceof String s) {
return Document.fromString(s);
}
if (value instanceof Number n) {
return Document.fromNumber(n.toString());
}
if (value instanceof Boolean b) {View on GitHub (pinned to 98a7beda4f)
Solutions
- Always place a literal (Filter.Value) on the value side of comparisons; compare against constants, not other fields
- If field-to-field comparison is needed, compute it differently (e.g. filter client-side) since Bedrock converter only supports literal comparisons
- Validate the tree before conversion: right operand must be instanceof Filter.Value
- Catch IllegalArgumentException and surface which comparison operand had the wrong type
Example fix
// before
Expression e = GT(new ExpressionText("price"), new ExpressionText("msrp")); // value side is an Expression
// after
Expression e = GT(new ExpressionText("price"), 99.99); // literal Value on the right Defensive patterns
Strategy: type-guard
Validate before calling
if (expr.left() != null && expr.right() != null && !(expr.right() instanceof Value)) { throw new IllegalArgumentException("Comparison value side must be a literal Value"); } Type guard
Object requireLiteral(Filter.Operand o) { if (o instanceof Value v) return v.value(); throw new IllegalArgumentException("Expected literal value operand, got: " + o.getClass()); } Try / catch
try { String filter = converter.convertExpression(expression); ... } catch (IllegalArgumentException e) { log.error("Comparison value must be literal: {}", e.getMessage()); /* rebuild filter with literals */ } Prevention
- Never compare field-to-field; compare against constants
- Keep keys on the left, literals on the right in comparisons
- Validate comparison operands before conversion
- Cover all comparison filters in unit tests for Bedrock KB
When it happens
Trigger: Building a comparison like GT(expr, expr) or EQ(key, anotherKey) where the right-hand side is an Expression instead of a literal Value, then converting via BedrockKnowledgeBaseFilterExpressionConverter or running similaritySearch with that filterExpression.
Common situations: Programmatic filter builders that put field references on the value side (field-to-field comparisons); copy-pasted filter code from stores that support key-to-key comparison; confusion between ExpressionText-as-key and value operand roles.
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
- Expected Expression but got:
- Filter type not supported:
- NOT operator negation failed for expression type: . Operand:
- Expected List for IN/NIN but got:
- The region '<region>' is not a valid region!
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/f3c10fbb43c68677.
Report an issue: GitHub.