apache/cassandra · error · InvalidRequestException
Invalid operation (%s) for non-UDT column %s
Error message
Invalid operation (%s) for non-UDT column %s
What it means
Cassandra throws this during preparation when a UDT field-update operation (udt.field = value) targets a column that is not a user-defined type. Only non-frozen UDT columns support per-field assignment; any other column type is rejected before field resolution.
Source
Thrown at src/java/org/apache/cassandra/cql3/Operation.java:297
return !(other instanceof SetValue);
}
}
public static class SetField implements RawUpdate
{
private final FieldIdentifier field;
private final Term.Raw value;
public SetField(FieldIdentifier field, Term.Raw value)
{
this.field = field;
this.value = value;
}
public Operation prepare(TableMetadata metadata, ColumnMetadata receiver, boolean canReadExistingState) throws InvalidRequestException
{
if (!receiver.type.isUDT())
throw new InvalidRequestException(String.format("Invalid operation (%s) for non-UDT column %s", toString(receiver), receiver.name));
else if (!receiver.type.isMultiCell())
throw new InvalidRequestException(String.format("Invalid operation (%s) for frozen UDT column %s", toString(receiver), receiver.name));
int fieldPosition = ((UserType) receiver.type).fieldPosition(field);
if (fieldPosition == -1)
throw new InvalidRequestException(String.format("UDT column %s does not have a field named %s", receiver.name, field));
Term val = value.prepare(metadata.keyspace, UserTypes.fieldSpecOf(receiver, fieldPosition));
return new UserTypes.SetterByField(receiver, field, val);
}
protected String toString(ColumnSpecification column)
{
return String.format("%s.%s = %s", column.name, field, value);
}
public boolean isCompatibleWith(RawUpdate other)
{View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Confirm the column type with DESCRIBE TABLE; use plain assignment for non-UDT columns
- If field-wise updates are wanted, change the column to a (non-frozen) UDT and migrate data
- For tuples, replace the whole tuple value instead of assigning a field
Example fix
// before (address is tuple<text,text>)
UPDATE users SET address.city = 'NYC' WHERE id = 1;
// after
UPDATE users SET address = ('NYC','10001') WHERE id = 1; -- replace whole tuple Defensive patterns
Strategy: validation
Validate before calling
AbstractType<?> t = tm.getColumn(col).getType(); if (!t.isUDT()) throw new IllegalArgumentException(col + " is not a UDT; use plain assignment");
Type guard
boolean isUdt(AbstractType<?> t) { return t.isUDT(); } Prevention
- Check system_schema.columns type before field-level updates
- Do not conflate tuples with UDTs; they need different update styles
- Generate data-access code from the live schema
When it happens
Trigger: Executing 'UPDATE t SET mycol.fieldname = v WHERE ...' where mycol is not a UDT (scalar, collection, tuple); e.g. using field syntax on a tuple or text column.
Common situations: Column type confusion between tuple and UDT (both use dot-notation concepts); schema changed from UDT to another type; copy-pasted queries across tables.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Not enough bytes to read size of %dth field %s
- Not enough bytes to read %dth field %s
- Invalid operation (%s) for frozen UDT column %s
- UDT column %s does not have a field named %s
- Invalid operation (%s) for non-numeric and non-text type %s
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/b88d3a5c9e8e7731.
Report an issue: GitHub.