apache/cassandra · error · InvalidRequestException
Invalid element access syntax for set column %s
Error message
Invalid element access syntax for set column %s
What it means
Cassandra throws this when element-access (index/key) syntax is applied to a SET column. Sets have no per-element values — only membership — so during `prepareCollectionElement` the switch on the collection kind handles LIST and MAP (via `indexSpecOf`/`keySpecOf`) but explicitly rejects SET, since there is no element spec to prepare.
Source
Thrown at src/java/org/apache/cassandra/cql3/ElementExpression.java:252
return new ElementExpression(kind,
userType.type(fieldPosition),
UTF8Type.instance,
new Constants.Value(udtField.bytes));
}
private Term prepareCollectionElement(ColumnMetadata receiver)
{
ColumnSpecification elementSpec;
switch ((((CollectionType<?>) receiver.type.unwrap()).kind))
{
case LIST:
elementSpec = Lists.indexSpecOf(receiver);
break;
case MAP:
elementSpec = Maps.keySpecOf(receiver);
break;
case SET:
throw invalidRequest("Invalid element access syntax for set column %s", receiver.name);
default:
throw new AssertionError();
}
return rawCollectionElement.prepare(receiver.ksName, elementSpec);
}
/**
* Checks if this raw expression contains bind markers.
* @return {@code true} if this raw expression contains bind markers, {@code false} otherwise.
*/
public boolean containsBindMarkers()
{
return rawCollectionElement != null && rawCollectionElement.containsBindMarker();
}
@OverrideView on GitHub (pinned to 88fd0f6a0e)
Solutions
- For sets, replace element access with whole-value comparison (`tags = {'a','b'}`) or membership via CONTAINS in WHERE clauses
- To modify a set, replace it entirely with `SET tags = {...}`, or `SET tags = tags + {'x'}` / `- {'x'}` for add/remove
- If per-key assignment is needed, change the column to a `map<...>` type and migrate the data
- If only membership tests are needed and ordering/duplication rules allow it, model the data as a map instead
Example fix
// before
UPDATE users SET tags['vip'] = 'true' WHERE id = 1; -- tags is set<text>
// after
UPDATE users SET tags = tags + {'vip'} WHERE id = 1; Defensive patterns
Strategy: validation
Validate before calling
// Reject element-access plans on set columns before executing
if (columnType.unwrap() instanceof SetType)
throw new IllegalArgumentException("Element access not supported on set column " + columnType);
// use set = set + {'x'} / set - {'x'} or whole-value comparison instead Type guard
boolean isSetColumn(ColumnMetadata col) {
return col.getType().unwrap() instanceof SetType;
} Prevention
- Model per-key assignments as map<k,v>, not set<v>
- Use set union (+) / difference (-) for element add/remove
- Never copy element-access query templates between map, list, and set columns without checking kinds
- Document per-column collection kind in the data-access layer
When it happens
Trigger: Statements like `UPDATE t SET tags['x'] = 'y'` or `WHERE tags['x'] = ...` where `tags` is `set<text>`; trying to assign or compare an element of a set instead of using whole-set operations.
Common situations: Developer confusion between set and map semantics (sets have keys-as-values but no values); migrating a column from map to set (or vice versa) while retaining old element-access queries; copying query templates between columns of different collection kinds.
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 operation (%s) for set column %s
- Invalid element access syntax for non-collection column %s
- REVOKE operation is not supported by AllowAllAuthorizer
- Counters are not allowed inside collections:
- Durations are not allowed inside sets:
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/bdc8528b486dee19.
Report an issue: GitHub.