apache/cassandra · error · MarshalException

Tuple is missing items

Error message

Tuple is missing items (expected %s): %s

What it means

In TupleType.fromJSONObject, if the JSON list has fewer elements than the tuple type declares, this MarshalException is thrown. Unlike variable-length bind semantics, a JSON tuple literal must supply an item for every declared field (use explicit nulls where allowed).

Solutions

  1. Provide all declared fields in the array, using null for fields that should be null
  2. Re-check the tuple arity in the current schema
  3. Regenerate payloads from updated schema definitions after ALTER
  4. Validate array length client-side before insert

Example fix

// before: tuple<int,int> missing second field
{"t": [1]}
// after
{"t": [1, null]}
Defensive patterns

Strategy: validation

Validate before calling

if (((List<?>) parsed).size() < types.size()) throw new IllegalArgumentException("JSON tuple is missing items; use explicit nulls");

Try / catch

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

Prevention

When it happens

Trigger: INSERT JSON with a shorter array, e.g. tuple<int,int> given [1]; calling fromJSONObject with a partial list.

Common situations: Application serializers omitting trailing null fields; schema added a field to the tuple and old payloads no longer match; hand-written JSON in scripts/tests.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

        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));
            }
        }

        return new MultiElements.DelayedValue(this, terms);
    }

View on GitHub (pinned to 88fd0f6a0e)