apache/cassandra · error · IllegalArgumentException

appendAll() can only be called on non-frozen collections

Error message

appendAll() can only be called on non-frozen collections

What it means

Row.SimpleBuilder.add() is called with overwriteForCollection=true (via appendAll) only when the target column is a non-frozen (multi-cell) collection. If the column type is not a multi-cell collection, add throws IllegalArgumentException, because appending elements to a frozen collection is not a valid write semantics — frozen collections must be replaced wholesale.

Solutions

  1. Use plain set/add (overwriteForCollection=false) to replace the frozen collection value instead of appendAll
  2. Change the schema column to a non-frozen collection (e.g. map<text,text> instead of frozen<map<text,text>>) if append semantics are desired
  3. Check ColumnMetadata.getType() with an assertion before calling appendAll in builder code

Example fix

// before
rowBuilder.appendAll("tags", listOf("a","b"));  // tags is frozen<list<text>>
// after
rowBuilder.add("tags", listOf("a","b"));       // replace frozen collection wholesale
Defensive patterns

Strategy: type-guard

Validate before calling

ColumnMetadata column = getColumn(columnName);
if (overwriteForCollection && !(column.type.isMultiCell() && column.type.isCollection()))
    throw new IllegalArgumentException(columnName + " is not a non-frozen collection");

Type guard

boolean isAppendable(ColumnMetadata c) { return c.type.isMultiCell() && c.type.isCollection(); }

Try / catch

try { builder.appendAll(col, value); } catch (IllegalArgumentException e) { if (e.getMessage().contains("appendAll")) { builder.add(col, value); } else throw e; }

Prevention

When it happens

Trigger: Calling builder.appendAll("col", value) (or add with overwriteForCollection=true) on a frozen<list/map/set> column, or on a non-collection column entirely.

Common situations: Schema changed from non-frozen to frozen collections (or the test/schema uses frozen) while the builder code still calls appendAll; developer confuses appendAll with set semantics on frozen collections in test builders.

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/fc81a6bb542e7984. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/db/SimpleBuilders.java:386

        }

        public Row.SimpleBuilder add(String columnName, Object value)
        {
            return add(columnName, value, true);
        }

        public Row.SimpleBuilder appendAll(String columnName, Object value)
        {
            return add(columnName, value, false);
        }

        private Row.SimpleBuilder add(String columnName, Object value, boolean overwriteForCollection)
        {
            maybeInit();
            ColumnMetadata column = getColumn(columnName);

            if (!overwriteForCollection && !(column.type.isMultiCell() && column.type.isCollection()))
                throw new IllegalArgumentException("appendAll() can only be called on non-frozen collections");

            columns.add(column);

            if (!column.type.isMultiCell())
            {
                builder.addCell(cell(column, toByteBuffer(value, column.type), null));
                return this;
            }

            assert column.type instanceof CollectionType : "Collection are the only multi-cell types supported so far";

            if (value == null)
            {
                builder.addComplexDeletion(column, DeletionTime.build(timestamp, nowInSec));
                return this;
            }

            // Erase previous entry if any.

View on GitHub (pinned to 88fd0f6a0e)