apache/cassandra · error · InvalidRequestException

Invalid tuple literal for %s: too many elements. Type %s exp

Error message

Invalid tuple literal for %s: too many elements. Type %s expects %d but got %d

What it means

Cassandra throws this when a tuple literal in a CQL statement contains more values than the target column's tuple type defines components for. Tuples in Cassandra have a fixed arity: a column declared, say, `frozen<tuple<int, text>>` accepts exactly 2 elements and no more. During statement validation (validateTupleAssignableTo, invoked via testTupleAssignment), the element list is compared element-by-element against the receiver's TupleType, and any excess element triggers this InvalidRequestException before execution.

Source

Thrown at src/java/org/apache/cassandra/cql3/terms/Tuples.java:189

    /**
     * Checks if the tuple with the specified elements can be assigned to the specified column.
     *
     * @param receiver the receiving column
     * @param elements the tuple elements
     * @throws InvalidRequestException if the tuple cannot be assigned to the specified column.
     */
    public static void validateTupleAssignableTo(ColumnSpecification receiver,
                                                 List<? extends AssignmentTestable> elements)
    {
        if (!checkIfTupleType(receiver.type))
            throw invalidRequest("Invalid tuple type literal for %s of type %s", receiver.name, receiver.type.asCQL3Type());

        TupleType tt = getTupleType(receiver.type);
        for (int i = 0; i < elements.size(); i++)
        {
            if (i >= tt.size())
            {
                throw invalidRequest("Invalid tuple literal for %s: too many elements. Type %s expects %d but got %d",
                                     receiver.name, tt.asCQL3Type(), tt.size(), elements.size());
            }

            AssignmentTestable value = elements.get(i);
            ColumnSpecification spec = componentSpecOf(receiver, i);
            if (!value.testAssignment(receiver.ksName, spec).isAssignable())
                throw invalidRequest("Invalid tuple literal for %s: component %d is not of type %s",
                                     receiver.name, i, spec.type.asCQL3Type());
        }
    }

    /**
     * Tests that the tuple with the specified elements can be assigned to the specified column.
     *
     * @param receiver the receiving column
     * @param elements the tuple elements
     */
    public static AssignmentTestable.TestResult testTupleAssignment(ColumnSpecification receiver,

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Count the elements in the tuple literal and compare with the column definition (`DESCRIBE TABLE` or system_schema.columns shows the tuple type); remove extra elements so it matches the declared arity.
  2. If the extra element should be stored, ALTER the column to a wider tuple type (note: Cassandra only supports adding components at the end, e.g. ALTER TABLE ... ALTER c TYPE tuple<int, text, boolean> in older versions or recreate the column), then update the statement.
  3. If element count is dynamic in application code, validate `values.size() <= declaredTupleSize` before building the CQL literal, or use a separate collection column (list/set/map) instead of a tuple.
  4. After any tuple type change, restart/refresh prepared statement caches so stale literals against the old type are revalidated.

Example fix

// before: column is frozen<tuple<int, text>> (2 components)
INSERT INTO t (k, c) VALUES (1, (1, 'a', true));

// after: literal arity matches the declared tuple type
INSERT INTO t (k, c) VALUES (1, (1, 'a'));
Defensive patterns

Strategy: validation

Validate before calling

TupleType tt = (TupleType) column.getType();
if (values.size() > tt.size())
    throw new IllegalArgumentException(
        String.format("tuple for column %s expects at most %d elements, got %d",
                      column.getName(), tt.size(), values.size()));

Prevention

When it happens

Trigger: Executing INSERT/UPDATE/DELETE with a tuple literal like `c = (1, 'a', true)` against a column of type `tuple<int, text>`; calling `Tuples.validateTupleAssignableTo(receiver, elements)` (or `testTupleAssignment`) with `elements.size() > tupleType.size()`; binding a user-supplied list into a tuple column without checking arity; preparing statements where a schema change shortened the tuple type while cached literals still supply the old element count.

Common situations: Application code building tuple values dynamically from a list of unknown length; a schema migration that reduced the number of tuple components while old application versions still send the larger literal; typos in hand-written CQL where an extra value is pasted into the tuple; ORM/driver mapping layers that serialize the whole row object into a tuple field.

Related errors


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