apache/cassandra · error · InvalidRequestException
Cannot alter user type
Error message
Cannot alter user type %s as it is still used in INITCOND by aggregates %s
What it means
ALTER TYPE ... RENAME refuses to rename fields of a UDT that is referenced as the INITCOND (initial condition/state) type of one or more user-defined aggregates in the same keyspace. The aggregate's initial condition value is stored against the old field layout, so renaming fields would corrupt its interpretation. The statement lists the dependent aggregates in the error.
Solutions
- DROP the dependent aggregates first (note their definitions), run the ALTER TYPE RENAME, then recreate the aggregates
- If the INITCOND is not needed, recreate the aggregate without INITCOND so it no longer references the UDT
- Move the aggregate to a different (non-UDT) state type before renaming
Example fix
// before ALTER TYPE myks.agg_state RENAME old_field TO new_field; -- fails // after DROP AGGREGATE myks.my_agg; -- recreate afterwards ALTER TYPE myks.agg_state RENAME old_field TO new_field;
Defensive patterns
Strategy: validation
Validate before calling
// Check for UDAs whose INITCOND references the UDT before renaming:
ResultSet rs = session.execute("SELECT aggregate_name FROM system_schema.aggregates WHERE keyspace_name='myks'");
// drop/recreate any aggregates whose INITCOND uses the UDT before ALTER TYPE ... RENAME Try / catch
try { session.execute(renameCql); }
catch (InvalidQueryException e) {
if (e.getMessage().contains("still used in INITCOND")) { /* drop listed aggregates, rename, recreate */ }
else throw e;
} Prevention
- Track UDA <-> UDT dependencies in schema migration notes
- Drop and recreate aggregates as part of the same migration script when altering their state UDTs
- Prefer simple (non-UDT) INITCOND types for aggregates
When it happens
Trigger: Running `ALTER TYPE myks.state RENAME ...` while a UDA created with `CREATE AGGREGATE ... INITCOND <value of that UDT>` still exists in the keyspace.
Common situations: Cleaning up legacy schema after analytics workloads created UDAs over UDT state types; forgetting that INITCOND ties the aggregate to the type definition.
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
- Altering field types is no longer supported
- Argument ' ' cannot be frozen; remove frozen<> modifier from
- Cannot add new field
- Cannot add new field
- Cannot create index on non-frozen UDT column
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/dfa1aff12ad815d0.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/AlterTypeStatement.java:215
@Override
public boolean compatibleWith(ClusterMetadata metadata)
{
return metadata.directory.commonSerializationVersion.isAtLeast(Version.V0);
}
UserType apply(KeyspaceMetadata keyspace, UserType userType)
{
List<String> dependentAggregates =
keyspace.userFunctions
.udas()
.filter(uda -> null != uda.initialCondition() && uda.stateType().referencesUserType(userType.name))
.map(uda -> uda.name().toString())
.collect(toList());
if (!dependentAggregates.isEmpty())
{
throw ire("Cannot alter user type %s as it is still used in INITCOND by aggregates %s",
userType.getCqlTypeName(),
join(", ", dependentAggregates));
}
List<FieldIdentifier> fieldNames = new ArrayList<>(userType.fieldNames());
renamedFields.forEach((oldName, newName) ->
{
int idx = userType.fieldPosition(oldName);
if (idx < 0)
{
if (!ifFieldExists)
throw ire("Unkown field %s in user type %s", oldName, userType.getCqlTypeName());
return;
}
fieldNames.set(idx, newName);
});
View on GitHub (pinned to 88fd0f6a0e)