apache/cassandra · error · InvalidRequestException

Attempted to set an element on a list which is null

Error message

Attempted to set an element on a list which is null

What it means

Thrown when assigning a list element by index but the target list in the prefetched row is empty/null (existingSize == 0). Setting by index requires an existing element to address; there is nothing at any index of a null/empty list.

Solutions

  1. Initialize the list first (e.g. `SET l = ['v']`) or append instead of indexing when the list may be empty
  2. Check list contents with a SELECT before indexed writes in application logic
  3. Use appends (l = l + [...]) which work on missing lists

Example fix

// before
UPDATE t SET l[0] = 'v' WHERE k = 0; // l missing
// after
UPDATE t SET l = l + ['v'] WHERE k = 0; // or ensure l exists first
Defensive patterns

Strategy: validation

Validate before calling

Row row = session.execute("SELECT l FROM t WHERE k=?", key).one(); if (row == null || row.getList("l", String.class).isEmpty()) throw new IllegalStateException("list missing/empty");

Try / catch

try { session.execute(stmt); } catch (InvalidQueryException e) { if (e.getMessage().contains("list which is null")) { /* initialize list or append instead */ } else throw e; }

Prevention

When it happens

Trigger: `UPDATE t SET l[0] = 'v'` executed when row's list l does not exist or is empty; the read-before-write (prefetch) returns no list cells.

Common situations: Setting an element on a list column that was never initialized for the row; race where another writer cleared the list between read and write; assuming lists auto-create like collections appends do.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/terms/Lists.java:372

            // we should not get here for frozen lists
            assert column.type.isMultiCell() : "Attempted to set an individual element on a frozen list";

            Guardrails.readBeforeWriteListOperationsEnabled
            .ensureEnabled("Setting of list items by index requiring read before write", builder.clientState);

            ByteBuffer index = idx.bindAndGet(builder);
            ByteBuffer value = t.bindAndGet(builder);

            if (index == null)
                throw new InvalidRequestException("Invalid null value for list index");
            if (index == ByteBufferUtil.UNSET_BYTE_BUFFER)
                throw new InvalidRequestException("Invalid unset value for list index");

            Row existingRow = builder.getPrefetchedRow(partitionKey, builder.currentClustering());
            int existingSize = existingSize(existingRow, column);
            int idx = ByteBufferUtil.toInt(index);
            if (existingSize == 0)
                throw new InvalidRequestException("Attempted to set an element on a list which is null");
            if (idx < 0 || idx >= existingSize)
                throw new InvalidRequestException(String.format("List index %d out of bound, list has size %d", idx, existingSize));

            CellPath elementPath = existingRow.getComplexColumnData(column).getCellByIndex(idx).path();
            if (value == null)
                builder.addTombstone(column, elementPath);
            else if (value != ByteBufferUtil.UNSET_BYTE_BUFFER)
                builder.addCell(column, elementPath, value);
        }
    }

    public static class Appender extends Operation
    {
        public Appender(ColumnMetadata column, Term t)
        {
            super(column, t);
        }

View on GitHub (pinned to 88fd0f6a0e)