{"record":{"id":"dfa1aff12ad815d0","repo":"apache/cassandra","slug":"cannot-alter-user-type-s-as-it-is-still-used-in-i","errorCode":null,"errorMessage":"Cannot alter user type %s as it is still used in INITCOND by aggregates %s","messagePattern":"Cannot alter user type (.+?) as it is still used in INITCOND by aggregates (.+?)","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/AlterTypeStatement.java","lineNumber":215,"sourceCode":"\n        @Override\n        public boolean compatibleWith(ClusterMetadata metadata)\n        {\n            return metadata.directory.commonSerializationVersion.isAtLeast(Version.V0);\n        }\n\n        UserType apply(KeyspaceMetadata keyspace, UserType userType)\n        {\n            List<String> dependentAggregates =\n                keyspace.userFunctions\n                        .udas()\n                        .filter(uda -> null != uda.initialCondition() && uda.stateType().referencesUserType(userType.name))\n                        .map(uda -> uda.name().toString())\n                        .collect(toList());\n\n            if (!dependentAggregates.isEmpty())\n            {\n                throw ire(\"Cannot alter user type %s as it is still used in INITCOND by aggregates %s\",\n                          userType.getCqlTypeName(),\n                          join(\", \", dependentAggregates));\n            }\n\n            List<FieldIdentifier> fieldNames = new ArrayList<>(userType.fieldNames());\n\n            renamedFields.forEach((oldName, newName) ->\n            {\n                int idx = userType.fieldPosition(oldName);\n                if (idx < 0)\n                {\n                    if (!ifFieldExists)\n                        throw ire(\"Unkown field %s in user type %s\", oldName, userType.getCqlTypeName());\n                    return;\n                }\n                fieldNames.set(idx, newName);\n            });\n","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/AlterTypeStatement.java#L197-L233","documentation":"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.","triggerScenarios":"Running `ALTER TYPE myks.state RENAME ...` while a UDA created with `CREATE AGGREGATE ... INITCOND <value of that UDT>` still exists in the keyspace.","commonSituations":"Cleaning up legacy schema after analytics workloads created UDAs over UDT state types; forgetting that INITCOND ties the aggregate to the type definition.","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"],"exampleFix":"// before\nALTER TYPE myks.agg_state RENAME old_field TO new_field; -- fails\n// after\nDROP AGGREGATE myks.my_agg; -- recreate afterwards\nALTER TYPE myks.agg_state RENAME old_field TO new_field;","handlingStrategy":"validation","validationCode":"// Check for UDAs whose INITCOND references the UDT before renaming:\nResultSet rs = session.execute(\"SELECT aggregate_name FROM system_schema.aggregates WHERE keyspace_name='myks'\");\n// drop/recreate any aggregates whose INITCOND uses the UDT before ALTER TYPE ... RENAME","typeGuard":null,"tryCatchPattern":"try { session.execute(renameCql); }\ncatch (InvalidQueryException e) {\n    if (e.getMessage().contains(\"still used in INITCOND\")) { /* drop listed aggregates, rename, recreate */ }\n    else throw e;\n}","preventionTips":["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"],"tags":["cassandra","cql","udt","uda","aggregate"],"backgroundTag":"unsupported-operation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}