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

  1. Always place a literal (Filter.Value) on the value side of comparisons; compare against constants, not other fields
  2. If field-to-field comparison is needed, compute it differently (e.g. filter client-side) since Bedrock converter only supports literal comparisons
  3. Validate the tree before conversion: right operand must be instanceof Filter.Value
  4. 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

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


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