apache/cassandra · error · InvalidRequestException
Invalid operation (%s) for tuple column %s
Error message
Invalid operation (%s) for tuple column %s
What it means
Cassandra throws this during preparation when a counter-style arithmetic operation (col = col + <n>, i.e. Constants.Adder) targets a tuple column. Tuples are neither collections (multi-cell) nor numeric/text scalars eligible for addition, so the adder is rejected.
Source
Thrown at src/java/org/apache/cassandra/cql3/Operation.java:337
return !(other instanceof SetValue);
}
}
public static class Addition implements RawUpdate
{
private final Term.Raw value;
public Addition(Term.Raw value)
{
this.value = value;
}
public Operation prepare(TableMetadata metadata, ColumnMetadata receiver, boolean canReadExistingState) throws InvalidRequestException
{
if (!(receiver.type instanceof CollectionType))
{
if (receiver.type instanceof TupleType)
throw new InvalidRequestException(String.format("Invalid operation (%s) for tuple column %s", toString(receiver), receiver.name));
if (canReadExistingState)
{
if (!(receiver.type instanceof NumberType<?>) && !(receiver.type instanceof StringType))
throw new InvalidRequestException(String.format("Invalid operation (%s) for non-numeric and non-text type %s", toString(receiver), receiver.name));
}
else
{
if (!(receiver.type instanceof CounterColumnType))
throw new InvalidRequestException(String.format("Invalid operation (%s) for non counter column %s", toString(receiver), receiver.name));
}
return new Constants.Adder(receiver, value.prepare(metadata.keyspace, receiver));
}
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)
{View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Replace the whole tuple value with a plain assignment: SET mytuple = (v1, v2)
- Remove the arithmetic/append operation for tuple columns in application code
- If incremental semantics are needed, split the tuple into separate scalar/counter columns
Example fix
// before (loc tuple<int,int>) UPDATE points SET loc = loc + (1,1) WHERE id = 1; // after UPDATE points SET loc = (2,3) WHERE id = 1; -- assign a full new tuple
Defensive patterns
Strategy: validation
Validate before calling
AbstractType<?> t = tm.getColumn(col).getType(); if (t instanceof TupleType) throw new IllegalArgumentException(col + " is a tuple; assign full values, no +/- operations");
Type guard
boolean isTuple(AbstractType<?> t) { return t instanceof TupleType; } Prevention
- Only apply arithmetic ops to numeric/counter columns
- Keep a registry of column types in the query builder
- Review generic 'append' helpers for type restrictions
When it happens
Trigger: Using increment syntax like 'UPDATE t SET mytuple = mytuple + something' or any +/- operation on a tuple-typed column; the prepare() path for Adder hits the TupleType check first.
Common situations: Confusing tuple columns with counters or collections; generic update code that appends '+' operations to any column; schema migrated from a numeric column to a tuple.
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
- Not enough bytes to read size of %dth component
- Not enough bytes to read %dth component
- Secondary indexes are not supported on tuples containing dur
- category %s not found in %s
- GRANT operation is not supported by AllowAllAuthorizer
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/08fa64d8bc4d4175.
Report an issue: GitHub.