apache/cassandra · error · InvalidRequestException

%s does not support complex column updates

Error message

%s does not support complex column updates

What it means

AbstractMutableLazyVirtualTable.applyRow converts a row mutation into (columns, values) pairs fed to the backing map, but it only supports simple (non-collection, non-complex) cells. Multi-element cells (lists, sets, maps, UDTs) arrive as ComplexColumnData and cannot be represented, so InvalidRequestException is thrown.

Source

Thrown at src/java/org/apache/cassandra/db/virtual/AbstractMutableLazyVirtualTable.java:102

    }

    private void applyRow(Object[] pks, Row row)
    {
        Object[] cks = row.clustering().kind() == STATIC_CLUSTERING ? null : composeClusterings(row.clustering(), metadata());
        if (!row.deletion().isLive())
        {
            applyRowDeletion(pks, cks);
        }
        else
        {
            ColumnMetadata[] columns = new ColumnMetadata[row.columnCount()];
            Object[] values = new Object[row.columnCount()];
            int i = 0;
            for (ColumnData cd : row)
            {
                ColumnMetadata cm = cd.column();
                if (cm.isComplex())
                    throw new InvalidRequestException(metadata() + " does not support complex column updates");
                Cell cell = (Cell)cd;
                columns[i] = cm;
                if (!cell.isTombstone())
                    values[i] = cm.type.compose(cell.value(), cell.accessor());
                ++i;
            }
            Invariants.require(i == columns.length);
            applyRowUpdate(pks, cks, columns, values);
        }
    }

    public void apply(PartitionUpdate update)
    {
        TableMetadata metadata = metadata();
        Object[] pks = composePartitionKeys(update.partitionKey(), metadata);

        DeletionInfo deletionInfo = update.deletionInfo();
        if (!deletionInfo.getPartitionDeletion().isLive())

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Write only simple (non-collection) columns on mutable virtual tables
  2. Replace collection writes with multiple statements updating individual simple columns, if the table exposes them
  3. Check the virtual table's schema (DESCRIBE) and avoid complex columns entirely

Example fix

// before
UPDATE system_auth.something SET tags = ['a','b'] WHERE key = 'k';
// after
UPDATE system_auth.something SET tag_a = 'a', tag_b = 'b' WHERE key = 'k';
Defensive patterns

Strategy: validation

Validate before calling

for (ColumnMetadata cm : update.columns()) if (cm.isComplex()) throw new IllegalArgumentException("complex column " + cm + " unsupported on virtual table");

Try / catch

try { session.execute(updateStmt); } catch (InvalidRequestException e) { if (e.getMessage().contains("complex column updates")) rewriteWithSimpleColumns(); else throw e; }

Prevention

When it happens

Trigger: UPDATE/INSERT against a mutable virtual table setting a collection or UDT column, e.g. `UPDATE system.auth_roles SET options = {'x':1} ...` where the target virtual table defines a complex column or the statement writes one.

Common situations: Generic DML generators emitting collection writes; schema evolution adding collection columns to what used to be simple columns; users assuming virtual tables support the full CQL type system.

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