apache/cassandra · error · InvalidRequestException
Invalid comparison with an empty %s for operator "%s"
Error message
Invalid comparison with an empty %s for operator "%s"
What it means
During multi-cell (collection) comparison in restrictions/conditions, Cassandra unpacks the collection value into its elements and rejects values that are empty collections. An empty collection carries no elements to compare against, so any operator comparison against it is meaningless — the error reports the collection kind (list/map/set) and the operator used.
Source
Thrown at src/java/org/apache/cassandra/cql3/Operator.java:965
public boolean isSatisfiedBy(MultiElementType<?> type, ComplexColumnData leftOperand, ByteBuffer rightOperand)
{
throw new UnsupportedOperationException();
}
/**
* Unpack multi-cell elements checking for null value and empty collections
*
* @param type the {@code MultiElementType}
* @param value the value to unpack
* @return the multi-cell elements
* @throws org.apache.cassandra.exceptions.InvalidRequestException if the value is null or an empty collection
*/
List<ByteBuffer> unpackMultiCellElements(MultiElementType<?> type, ByteBuffer value)
{
checkTrue(value != null, "Invalid comparison with null for operator \"%s\"", this);
List<ByteBuffer> elements = type.unpack(value);
if (type.isCollection() && elements.isEmpty())
throw invalidRequest("Invalid comparison with an empty %s for operator \"%s\"", ((CollectionType<?>) type).kind, this);
return elements;
}
public static int serializedSize()
{
return 4;
}
public void validateFor(ColumnsExpression expression)
{
// this method is used only in restrictions, not in conditions where different rules apply for now
if (!isSupportedByRestrictionsOn(expression))
throw invalidRequest("%s cannot be used with %s relations", this, expression);
switch (expression.kind())
{
case SINGLE_COLUMN:
ColumnMetadata firstColumn = expression.firstColumn();View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Guard in application code: skip adding the collection restriction when the value is empty/null
- Replace the operator comparison with an equality check (`map_col = {}` is valid) if testing for emptiness is the intent
- Use `map_col CONTAINS KEY ...` / element-level conditions instead of whole-collection ordering operators
- Ensure bound-parameter defaults produce null (unset) rather than an empty collection when no filter is intended
Example fix
// before
stmt = stmt.bind(params.getOrDefault("tags", Collections.emptyMap())); // WHERE tags > ?
// after
Map<String,String> tags = params.get("tags");
if (tags != null && !tags.isEmpty()) stmt = stmt.bind(tags); else /* omit clause */; Defensive patterns
Strategy: validation
Validate before calling
// Skip empty-collection filters before binding parameters
if (collectionValue == null || isEmptyCollection(collectionValue)) {
// omit the restriction entirely; do not bind an empty collection into an operator comparison
}
boolean isEmptyCollection(Object v) {
return v instanceof Collection && ((Collection<?>) v).isEmpty()
|| v instanceof Map && ((Map<?, ?>) v).isEmpty();
} Type guard
boolean isNonEmptyCollection(Object v) {
if (v instanceof Map) return !((Map<?, ?>) v).isEmpty();
if (v instanceof Collection) return !((Collection<?>) v).isEmpty();
return false;
} Try / catch
try {
return session.execute(stmt.bind(value));
} catch (InvalidRequestException e) {
if (e.getMessage().contains("Invalid comparison with an empty")) {
// drop the collection filter and retry without it
return session.execute(stmtWithoutCollectionFilter);
}
throw e;
} Prevention
- Never bind default-initialized empty maps/lists as comparison parameters
- Use null/unset tokens for absent filters instead of empty collections
- Use equality (=) or CONTAINS predicates rather than ordering operators on collections
- Serialize optional filter values with explicit null-vs-empty semantics
When it happens
Trigger: CQL restrictions like `WHERE map_col > {}`, `WHERE list_col < [ ]`, or binding an empty collection value (e.g. from a Java empty Map/List serialized into the bound variable) into a multi-cell collection comparison with operators such as `<`, `>`, `<=`, `>=`.
Common situations: Application code passes an empty/default-initialized collection as a bound parameter; deserialized protobuf/JSON payloads default to empty collections; query builders emit comparison predicates for optional filters even when the collection is empty.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Invalid element access syntax for non-collection column %s
- Counters are not allowed inside collections:
- Non-frozen collections are not allowed inside collections:
- Invalid operation (%s) for set column %s
- Invalid null value for element selection on <columnName>
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/af4db909091538d5.
Report an issue: GitHub.