apache/cassandra · error · InvalidRequestException
Invalid operation (%s) for set column %s
Error message
Invalid operation (%s) for set column %s
What it means
Cassandra throws this during preparation when a keyed collection operation (map put-by-key or list set-by-index pattern) is applied to a set column. Sets have no keys or indices, so SetterByKey/index-style operations are invalid for them; only full assignment or set addition/subtraction is allowed.
Source
Thrown at src/java/org/apache/cassandra/cql3/Operation.java:261
this.selector = selector;
this.value = value;
}
public Operation prepare(TableMetadata metadata, ColumnMetadata receiver, boolean canReadExistingState) throws InvalidRequestException
{
if (!(receiver.type instanceof CollectionType))
throw new InvalidRequestException(String.format("Invalid operation (%s) for non collection column %s", toString(receiver), receiver.name));
else if (!(receiver.type.isMultiCell()))
throw new InvalidRequestException(String.format("Invalid operation (%s) for frozen collection column %s", toString(receiver), receiver.name));
switch (((CollectionType<?>)receiver.type).kind)
{
case LIST:
Term idx = selector.prepare(metadata.keyspace, Lists.indexSpecOf(receiver));
Term lval = value.prepare(metadata.keyspace, Lists.valueSpecOf(receiver));
return new Lists.SetterByIndex(receiver, idx, lval);
case SET:
throw new InvalidRequestException(String.format("Invalid operation (%s) for set column %s", toString(receiver), receiver.name));
case MAP:
Term key = selector.prepare(metadata.keyspace, Maps.keySpecOf(receiver));
Term mval = value.prepare(metadata.keyspace, Maps.valueSpecOf(receiver));
return new Maps.SetterByKey(receiver, key, mval);
}
throw new AssertionError();
}
protected String toString(ColumnSpecification column)
{
return String.format("%s[%s] = %s", column.name, selector, value);
}
public boolean isCompatibleWith(RawUpdate other)
{
// TODO: we could check that the other operation is not setting the same element
// too (but since the index/key set may be a bind variables we can't always do it at this point)
return !(other instanceof SetValue);View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Use set add/remove instead of key assignment: SET myset = myset + {'v'} or myset - {'v'}
- Verify the column type with DESCRIBE TABLE; if key->value semantics are needed, change the column to map<K,V> (via migration)
- Fix code generation/ORM mapping so sets never receive by-key operations
Example fix
// before (myset is set<text>)
UPDATE users SET myset['role'] = 'admin' WHERE id = 1;
// after
UPDATE users SET myset = myset + {'admin'} WHERE id = 1; Defensive patterns
Strategy: validation
Validate before calling
AbstractType<?> t = tm.getColumn(col).getType();
if (t instanceof CollectionType && ((CollectionType<?>) t).kind == CollectionType.Kind.SET)
throw new IllegalArgumentException("sets have no keys/indices; use + / - operators"); Type guard
boolean isSet(AbstractType<?> t) { return t instanceof CollectionType && ((CollectionType<?>) t).kind == CollectionType.Kind.SET; } Prevention
- Verify column kind (LIST/SET/MAP) before emitting element-level operations
- Use distinct repository methods for set vs map updates
- Document collection column kinds in the data-access layer
When it happens
Trigger: Using element/key assignment syntax on a set column, e.g. 'UPDATE t SET myset['k']='v' WHERE ...' or an index-style operation myset[0]=x where myset is set<T>; the prepare() switch on CollectionType.Kind reaches the SET case and rejects it.
Common situations: Confusion between set and map column types in the schema; application code templated for maps reused for sets; column type changed from map to set in a migration.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Invalid null value for element selection on <columnName>
- Invalid element access syntax for set column %s
- category %s not found in %s
- GRANT operation is not supported by AllowAllAuthorizer
- REVOKE operation is not supported by AllowAllAuthorizer
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/105b98ca6f1281d3.
Report an issue: GitHub.