apache/cassandra · error · MarshalException
Expected a list representation of a tuple, but got a
Error message
Expected a list representation of a tuple, but got a %s: %s
What it means
TupleType.fromJSONObject converts a parsed JSON value into a tuple Term. The JSON must be a list whose elements map to the tuple's fields. If the parsed object is not a List (e.g. a string, map, or number), this MarshalException is thrown with the value's Java class name and contents.
Solutions
- Send the tuple as a JSON array: [elem1, elem2, ...]
- Fix double-encoding by passing the parsed JSON structure, not a JSON string containing JSON
- Check the client serializer's mapping for tuple columns
- Validate the payload shape before INSERT JSON
Example fix
// before
{"t": {"0": 1, "1": 2}}
// after
{"t": [1, 2]} Defensive patterns
Strategy: type-guard
Validate before calling
Object parsed = JsonUtils.decodeJson(json);
if (!(parsed instanceof List)) throw new IllegalArgumentException("tuple JSON must be an array"); Type guard
boolean isTupleJson(Object parsed) { return parsed instanceof List; } Try / catch
try {
Term t = tupleType.fromJSONObject(parsed);
} catch (MarshalException e) {
throw new IllegalArgumentException("tuple JSON shape invalid: " + e.getMessage());
} Prevention
- Serialize tuple columns as JSON arrays, never maps or strings
- Avoid double-encoding JSON strings for tuple fields
- Test INSERT JSON payloads against the schema in CI
When it happens
Trigger: Inserting JSON where the tuple column is given an object/map instead of an array (e.g. {"t": {"a":1}} instead of {"t": [1,2]}); passing a JSON-encoded string that decodes to a non-list to fromJSONObject.
Common situations: Application JSON serializers emitting maps for tuples; double-encoded JSON strings (a string containing JSON) where decodeJson produces a scalar; cqlsh INSERT JSON with a malformed tuple field.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- Tuple contains extra items
- Tuple is missing items
- Invalid null element in list
- Invalid tuple literal for
- Invalid tuple literal for
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/0eb030cff7076be8.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/db/marshal/TupleType.java:495
else
{
AbstractType<?> type = type(i);
fieldString = ESCAPED_COLON_PAT.matcher(fieldString).replaceAll(COLON);
fieldString = ESCAPED_AT_PAT.matcher(fieldString).replaceAll(AT);
fields.add(type.fromString(fieldString));
}
}
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);
}View on GitHub (pinned to 88fd0f6a0e)