spring-projects/spring-ai · error · IllegalArgumentException
Expression of type %s requires a right operand
Error message
Expression of type %s requires a right operand
What it means
SimpleVectorStoreFilterExpressionEvaluator's right() helper unwraps the right operand of a Filter.Expression. If the right operand is null, it throws IllegalArgumentException naming the expression type. Binary filter expressions (EQ, IN, AND, OR, comparisons) all require a right operand.
Source
Thrown at spring-ai-vector-store/src/main/java/org/springframework/ai/vectorstore/SimpleVectorStoreFilterExpressionEvaluator.java:135
// A non-null right operand is silently ignored here.
case ISNULL -> metadataValue(left(expression), metadata) == null;
case ISNOTNULL -> metadataValue(left(expression), metadata) != null;
};
}
private Filter.Operand left(Filter.Expression expression) {
Filter.Operand left = expression.left();
if (left == null) {
throw new IllegalArgumentException(
"Expression of type %s requires a left operand".formatted(expression.type()));
}
return left;
}
private Filter.Operand right(Filter.Expression expression) {
Filter.Operand right = expression.right();
if (right == null) {
throw new IllegalArgumentException(
"Expression of type %s requires a right operand".formatted(expression.type()));
}
return right;
}
/**
* Extracts the metadata value for the given {@link Filter.Key} operand. Outer quotes
* ({@code "..."} or {@code '...'}) are stripped from the key name to match the format
* used by {@link FilterExpressionBuilder} and the text parser.
*/
private @Nullable Object metadataValue(Filter.Operand operand, Map<String, Object> metadata) {
if (operand instanceof Filter.Key key) {
String k = key.key();
if (k.length() >= 2
&& ((k.startsWith("\"") && k.endsWith("\"")) || (k.startsWith("'") && k.endsWith("'")))) {
k = k.substring(1, k.length() - 1);
}
return metadata.get(k);View on GitHub (pinned to 98a7beda4f)
Solutions
- Always supply a Filter.Value (or nested Filter.Expression) as the right operand when building Filter.Expression instances.
- Use FilterExpressionTextParser to parse filter strings, which guarantees well-formed operands.
- Null-check operands in any custom expression-building code before search.
Example fix
// before
new Filter.Expression(Filter.ExpressionType.GT, new Filter.Key("year"), null);
// after
new Filter.Expression(Filter.ExpressionType.GT, new Filter.Key("year"), new Filter.Value(2020)); Defensive patterns
Strategy: validation
Validate before calling
boolean isWellFormed(Filter.Expression e) {
return e != null && e.left() != null && e.right() != null;
} Type guard
boolean hasRightOperand(Filter.Expression e) { return e != null && e.right() != null; } Try / catch
try {
vectorStore.similaritySearch(request);
} catch (IllegalArgumentException ex) {
if (ex.getMessage().contains("requires a right operand")) {
// supply the missing Filter.Value and retry build
} else throw ex;
} Prevention
- Always wrap literals in Filter.Value on the right side
- Validate the full expression tree recursively before search
When it happens
Trigger: Passing a programmatically constructed Filter.Expression with null right operand into a SearchRequest filter, e.g. new Filter.Expression(GT, new Filter.Key("year"), null).
Common situations: Manual Filter.Expression construction where the value operand was forgotten; deserialization dropping the right side; builder code with a conditional value path that returns null.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Expression of type %s requires a left operand
- Expected a Key operand but got:
- Expected a Value operand but got:
- Cannot compare values of incompatible types %s and %s
- Cannot compare values of types %s and %s
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/28782daa3f0557d6.
Report an issue: GitHub.