apache/cassandra · error · InvalidRequestException

Invalid operation ( ) for frozen collection column

Error message

Invalid operation (%s) for frozen collection column %s

What it means

Cassandra throws this during statement preparation when a non-frozen-safe collection operation targets a frozen collection column. Frozen collections are updated as a single opaque blob, so granular in-place operations (append, set-by-index, put-by-key) are rejected; the whole value must be rewritten.

Solutions

  1. Rewrite the statement to replace the whole frozen value (SET col = <full new collection>)
  2. If granular updates are needed, migrate the column to a non-frozen collection (new column + copy data, since ALTER cannot un-freeze)
  3. Change the ORM/query builder to emit full-value replacement for frozen collections
  4. Re-model the schema so only the truly immutable collections stay frozen

Example fix

// before (tags frozen<set<text>>)
UPDATE users SET tags = tags + {'new'} WHERE id = 1;
// after
UPDATE users SET tags = {'a','new'} WHERE id = 1;  -- replace whole frozen value
Defensive patterns

Strategy: validation

Validate before calling

AbstractType<?> t = tm.getColumn(col).getType();
if (t instanceof CollectionType && !t.isMultiCell())
    throw new IllegalArgumentException(col + " is frozen; replace the whole value instead of partial updates");

Type guard

boolean isFrozenCollection(AbstractType<?> t) { return t instanceof CollectionType && !t.isMultiCell(); }

Try / catch

try { session.execute(update); } catch (InvalidRequestException e) { if (e.getMessage().contains("frozen collection")) replaceWholeValue(); else throw e; }

Prevention

When it happens

Trigger: Using operations like c[k]=v, c+=v, c+=... or list index assignment on a column declared frozen<list<T>>, frozen<map<K,V>> or frozen<set<T>>; e.g. 'UPDATE t SET tags = tags + {"x"}' where tags is frozen<set<text>>.

Common situations: Tables created with frozen collections carried over from pre-3.x modelling; developer assumes collections behave like non-frozen ones; ORM generates partial-update statements against frozen columns.

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/17dcb0eb5ffe33a0. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/Operation.java:252

    }

    public static class SetElement implements RawUpdate
    {
        private final Term.Raw selector;
        private final Term.Raw value;

        public SetElement(Term.Raw selector, Term.Raw value)
        {
            this.selector = selector;
            this.value = value;
        }

        public Operation prepare(TableMetadata metadata, ColumnMetadata receiver, boolean canReadExistingState) throws InvalidRequestException
        {
            if (!(receiver.type instanceof CollectionType))
                throw new InvalidRequestException(String.format("Invalid operation (%s) for non collection column %s", toString(receiver), receiver.name));
            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)
            {
                case LIST:
                    Term idx = selector.prepare(metadata.keyspace, Lists.indexSpecOf(receiver));
                    Term lval = value.prepare(metadata.keyspace, Lists.valueSpecOf(receiver));
                    return new Lists.SetterByIndex(receiver, idx, lval);
                case SET:
                    throw new InvalidRequestException(String.format("Invalid operation (%s) for set column %s", toString(receiver), receiver.name));
                case MAP:
                    Term key = selector.prepare(metadata.keyspace, Maps.keySpecOf(receiver));
                    Term mval = value.prepare(metadata.keyspace, Maps.valueSpecOf(receiver));
                    return new Maps.SetterByKey(receiver, key, mval);
            }
            throw new AssertionError();
        }

        protected String toString(ColumnSpecification column)

View on GitHub (pinned to 88fd0f6a0e)