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

  1. Send a proper JSON array for list columns, e.g. {"tags": ["a","b"]}.
  2. If sending a string, make it a JSON-encoded array string: "[\"a\",\"b\"]".
  3. 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

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


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