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

VectorType.fromJSONObject expects the parsed JSON value to be a JSON array (List). If the parsed object is any other JSON type (string, number, object, boolean), MarshalException is thrown naming the actual type received.

Source

Thrown at src/java/org/apache/cassandra/db/marshal/VectorType.java:319

        List<V> split = unpack(value, accessor);
        for (int i = 0; i < dimension; i++)
        {
            if (i > 0)
                sb.append(", ");
            sb.append(elementType.toJSONString(split.get(i), accessor, protocolVersion));
        }
        sb.append(']');
        return sb.toString();
    }

    @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;
        if (list.size() != dimension)
            throw new MarshalException(String.format("List had incorrect size: expected %d but given %d; %s", dimension, list.size(), list));
        List<Term> terms = new ArrayList<>(list.size());
        for (Object element : list)
        {
            if (element == null)
                throw new MarshalException("Invalid null element in list");
            terms.add(elementType.fromJSONObject(element));
        }

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

    @Override
    public boolean equals(Object o)

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Send the vector as a JSON array matching the dimension, e.g. [1.0, 2.0, 3.0]
  2. Fix upstream JSON generation so the vector field is always an array
  3. Validate the JSON structure before calling fromJSONObject

Example fix

// before
String json = "1.0, 2.0, 3.0"; // scalar-ish
term = vectorType.fromJSONObject(json);
// after
String json = "[1.0, 2.0, 3.0]"; // proper array
term = vectorType.fromJSONObject(json);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(parsed instanceof List)) throw new IllegalArgumentException("vector JSON must be an array, got " + (parsed == null ? "null" : parsed.getClass().getSimpleName()));

Type guard

static boolean isJsonArray(Object o) { return o instanceof List; }

Try / catch

try { term = vt.fromJSONObject(parsed); } catch (MarshalException e) { /* log payload shape, return 400 */ }

Prevention

When it happens

Trigger: Calling fromJSONObject with a JSON scalar or object, e.g. fromJSONObject("[1,2,3]" as raw non-array) or JSON input like {"v": ...} instead of [...]; also when a string is passed it is first decoded, and the decoded value must still be a list.

Common situations: JSON-based insert paths (JSON statements, spark connector, REST layers) where the vector column received a scalar or object instead of an array; malformed user JSON payloads.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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