{"record":{"id":"b94673599e045fac","repo":"apache/cassandra","slug":"invalid-operation-s-for-frozen-udt-column-s","errorCode":null,"errorMessage":"Invalid operation (%s) for frozen UDT column %s","messagePattern":"Invalid operation \\((.+?)\\) for frozen UDT column (.+?)","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/Operation.java","lineNumber":299,"sourceCode":"    }\n\n    public static class SetField implements RawUpdate\n    {\n        private final FieldIdentifier field;\n        private final Term.Raw value;\n\n        public SetField(FieldIdentifier field, Term.Raw value)\n        {\n            this.field = field;\n            this.value = value;\n        }\n\n        public Operation prepare(TableMetadata metadata, ColumnMetadata receiver, boolean canReadExistingState) throws InvalidRequestException\n        {\n            if (!receiver.type.isUDT())\n                throw new InvalidRequestException(String.format(\"Invalid operation (%s) for non-UDT column %s\", toString(receiver), receiver.name));\n            else if (!receiver.type.isMultiCell())\n                throw new InvalidRequestException(String.format(\"Invalid operation (%s) for frozen UDT column %s\", toString(receiver), receiver.name));\n\n            int fieldPosition = ((UserType) receiver.type).fieldPosition(field);\n            if (fieldPosition == -1)\n                throw new InvalidRequestException(String.format(\"UDT column %s does not have a field named %s\", receiver.name, field));\n\n            Term val = value.prepare(metadata.keyspace, UserTypes.fieldSpecOf(receiver, fieldPosition));\n            return new UserTypes.SetterByField(receiver, field, val);\n        }\n\n        protected String toString(ColumnSpecification column)\n        {\n            return String.format(\"%s.%s = %s\", column.name, field, value);\n        }\n\n        public boolean isCompatibleWith(RawUpdate other)\n        {\n            if (other instanceof SetField)\n                return !((SetField) other).field.equals(field);","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/Operation.java#L281-L317","documentation":"Cassandra throws this during preparation when a UDT field update is applied to a frozen UDT column. Frozen UDTs are stored as one immutable blob, so individual fields cannot be updated in place; the entire UDT value must be replaced.","triggerScenarios":"Executing 'UPDATE t SET myudt.field = v WHERE ...' where myudt is declared frozen<some_udt>; isMultiCell() returns false and prepare() rejects the field-level setter.","commonSituations":"Tables modelled before Cassandra 3.x / UDT unfreezing support; developer unaware the UDT was created with FROZEN; migration scripts that froze UDTs for compatibility.","solutions":["Replace the whole frozen UDT value: SET myudt = {field1: v1, field2: v2, ...}","If per-field updates are required, migrate to a non-frozen UDT column (add new column, copy data, drop old)","Update application/ORM code to always send complete frozen UDT values"],"exampleFix":"// before (address frozen<address_udt>)\nUPDATE users SET address.city = 'NYC' WHERE id = 1;\n// after\nUPDATE users SET address = {street:'5th Ave', city:'NYC', zip:'10001'} WHERE id = 1;","handlingStrategy":"validation","validationCode":"AbstractType<?> t = tm.getColumn(col).getType();\nif (t.isUDT() && !t.isMultiCell())\n    throw new IllegalArgumentException(col + \" is a frozen UDT; assign the complete value\");","typeGuard":"boolean isFrozenUdt(AbstractType<?> t) { return t.isUDT() && !t.isMultiCell(); }","tryCatchPattern":"try { session.execute(update); } catch (InvalidRequestException e) { if (e.getMessage().contains(\"frozen UDT\")) writeFullUdt(); else throw e; }","preventionTips":["Record FROZEN modifiers in your schema model and generate full-value writes for them","Prefer non-frozen UDTs when per-field updates are needed","Test update paths against the production schema shape"],"tags":["cql","cassandra","udt","frozen"],"backgroundTag":"unsupported-operation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}