apache/cassandra · error · MarshalException
Expected a list, but got a %s: %s
Error message
Expected a list, but got a %s: %s
What it means
ListType.fromJSONObject converts a parsed JSON value into a list Term. The JSON value must be a JSON array (or a string that decodes to one); if it is any other JSON type, a MarshalException is thrown naming the actual type received.
Source
Thrown at src/java/org/apache/cassandra/db/marshal/ListType.java:241
}
public List<byte[]> serializedValuesAsByteArrays(Iterator<Cell<?>> cells)
{
assert isMultiCell;
List<byte[]> bbs = new ArrayList<>();
while (cells.hasNext())
bbs.add(cells.next().valueAsArray());
return bbs;
}
@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, but got a %s: %s", parsed.getClass().getSimpleName(), parsed));
List<?> list = (List<?>) parsed;
List<Term> terms = new ArrayList<>(list.size());
for (Object element : list)
{
if (element == null)
throw new MarshalException("Invalid null element in list");
terms.add(elements.fromJSONObject(element));
}
return new MultiElements.DelayedValue(this, terms);
}
public ByteBuffer getSliceFromSerialized(ByteBuffer collection, ByteBuffer from, ByteBuffer to)
{
// We don't support slicing on lists so we don't need that function
throw new UnsupportedOperationException();View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Send a proper JSON array for list columns, e.g. {"tags": ["a","b"]}.
- If sending a string, make it a JSON-encoded array string: "[\"a\",\"b\"]".
- Validate payload shape client-side against the table schema before submitting.
Example fix
// before
{"tags": "a,b,c"}
// after
{"tags": ["a", "b", "c"]} Defensive patterns
Strategy: type-guard
Validate before calling
if (!(value instanceof List)) throw new IllegalArgumentException("list column expects a JSON array, got: " + (value == null ? "null" : value.getClass().getSimpleName())); Type guard
boolean isJsonArray(Object o) { return o instanceof List; } Try / catch
try { term = listType.fromJSONObject(parsed); } catch (MarshalException e) { throw new BadRequestException("Invalid list value: " + e.getMessage()); } Prevention
- Always send JSON arrays for list columns.
- If using string-encoded JSON, ensure the string itself is a valid JSON array.
- Add contract tests verifying payload shape against the table schema.
When it happens
Trigger: Using fromJson()/JSON INSERT with a list column whose JSON value is an object, string (not JSON-encoded array), number, or boolean.
Common situations: Clients send {"tags": {"a":1}} instead of an array; a scalar string like "a,b,c" is sent without JSON array encoding; producer/consumer schema drift on list columns.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Expected an ascii string, but got a %s: %s
- Expected a string representation of a uuid, but got a %s: %s
- Expected a short value, but got a %s: %s
- Error decoding JSON value for %s: %s
- (dynamic MarshalException message)
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/1132caf8e02be1d6.
Report an issue: GitHub.