apache/cassandra · error · MarshalException

Tuple contains extra items

Error message

Tuple contains extra items (expected %s): %s

What it means

In TupleType.fromJSONObject, after confirming the JSON is a list, the list's length is compared with the number of declared field types. If the list has more elements than the tuple type declares, this MarshalException is thrown. Tuples are fixed-arity, so extra JSON items are rejected.

Solutions

  1. Trim the JSON array to exactly the declared arity
  2. Re-check the table schema for the tuple definition
  3. ALTER the tuple type first if more fields are genuinely needed
  4. Add payload validation on the client before INSERT JSON

Example fix

// before: tuple<int,int> via INSERT JSON
{"t": [1, 2, 3]}
// after
{"t": [1, 2]}
Defensive patterns

Strategy: validation

Validate before calling

if (((List<?>) parsed).size() > types.size()) throw new IllegalArgumentException("JSON tuple has extra items");

Try / catch

try {
    tupleType.fromJSONObject(parsed);
} catch (MarshalException e) {
    throw new IllegalArgumentException("tuple JSON arity mismatch: " + e.getMessage());
}

Prevention

When it happens

Trigger: INSERT JSON with an array longer than the tuple arity, e.g. tuple<int,int> given [1,2,3]; calling fromJSONObject with a hand-built list of extra elements.

Common situations: Schema changed the tuple to fewer fields while the application still sends the old width; accidental comma/element duplication in generated JSON.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/db/marshal/TupleType.java:501

            }
        }
        return pack(fields);
    }

    @Override
    public Term fromJSONObject(Object parsed) throws MarshalException
    {
        if (parsed instanceof String)
            parsed = JsonUtils.decodeJson((String) parsed);

        if (!(parsed instanceof List))
            throw new MarshalException(String.format(
                    "Expected a list representation of a tuple, but got a %s: %s", parsed.getClass().getSimpleName(), parsed));

        List<?> list = (List<?>) parsed;

        if (list.size() > types.size())
            throw new MarshalException(String.format("Tuple contains extra items (expected %s): %s", types.size(), parsed));
        else if (types.size() > list.size())
            throw new MarshalException(String.format("Tuple is missing items (expected %s): %s", types.size(), parsed));

        List<Term> terms = new ArrayList<>(list.size());
        Iterator<AbstractType<?>> typeIterator = types.iterator();
        for (Object element : list)
        {
            if (element == null)
            {
                typeIterator.next();
                terms.add(Constants.NULL_VALUE);
            }
            else
            {
                terms.add(typeIterator.next().fromJSONObject(element));
            }
        }

View on GitHub (pinned to 88fd0f6a0e)