apache/dubbo · error · ClassCastException

value %s for idx %d in %s is not object

Error message

value %s for idx %d in %s is not object

What it means

Thrown by AbstractJsonUtilImpl.checkObjectList(List) when iterating rawList and an element is not a Map. The method casts an unchecked List<?> into List<Map<String,?>>, validating each entry; the first non-Map entry aborts with a ClassCastException naming the value, its index, and the whole list.getListOfObjects delegates to getList then checkObjectList, so the same exception surfaces through that path.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/AbstractJsonUtilImpl.java:229

        Object value = obj.get(key);
        if (!(value instanceof String)) {
            throw new ClassCastException(
                    String.format("value '%s' for key '%s' in '%s' is not String", value, key, obj));
        }
        return (String) value;
    }

    /**
     * Casts a list of unchecked JSON values to a list of checked objects in Java type.
     * If the given list contains a value that is not a Map, throws an exception.
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<Map<String, ?>> checkObjectList(List<?> rawList) {
        assert rawList != null;
        for (int i = 0; i < rawList.size(); i++) {
            if (!(rawList.get(i) instanceof Map)) {
                throw new ClassCastException(
                        String.format("value %s for idx %d in %s is not object", rawList.get(i), i, rawList));
            }
        }
        return (List<Map<String, ?>>) rawList;
    }

    /**
     * Casts a list of unchecked JSON values to a list of String. If the given list
     * contains a value that is not a String, throws an exception.
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<String> checkStringList(List<?> rawList) {
        assert rawList != null;
        for (int i = 0; i < rawList.size(); i++) {
            if (!(rawList.get(i) instanceof String)) {
                throw new ClassCastException(
                        String.format("value '%s' for idx %d in '%s' is not string", rawList.get(i), i, rawList));

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Validate or filter the list before calling checkObjectList: rawList.stream().filter(Map.class::isInstance).map(m -> (Map<String,?>) m).collect(toList()).
  2. If the schema requires all-object entries, reject/fix the upstream payload that produced a scalar entry.
  3. Use getList (untyped) if you must tolerate heterogeneous entries, then handle each element by type.
  4. Catch ClassCastException and report the offending index for triage.

Example fix

// before
List<Map<String,?>> rows = jsonUtil.checkObjectList(raw); // contains a stray String
// after - filter to objects only
List<Map<String,?>> rows = raw.stream()
    .filter(Map.class::isInstance)
    .map(m -> (Map<String,?>) m)
    .collect(java.util.stream.Collectors.toList());
Defensive patterns

Strategy: type-guard

Validate before calling

List<?> raw = ...;
for (Object e : raw) {
    if (!(e instanceof Map)) {
        // filter or reject before calling checkObjectList
        raw = raw.stream().filter(Map.class::isInstance).collect(java.util.stream.Collectors.toList());
        break;
    }
}
return jsonUtil.checkObjectList(raw);

Type guard

private static boolean allObjects(List<?> rawList) {
    for (Object e : rawList) if (!(e instanceof Map)) return false;
    return true;
}

Try / catch

try {
    return jsonUtil.checkObjectList(rawList);
} catch (ClassCastException e) {
    // message names the offending index; fall back to filtering objects only
    return rawList.stream()
        .filter(Map.class::isInstance)
        .map(m -> (Map<String,?>) m)
        .collect(java.util.stream.Collectors.toList());
}

Prevention

When it happens

Trigger: jsonUtil.checkObjectList(rawList) (or getListOfObjects(obj,key)) where rawList contains at least one element that is not a Map — e.g. ["a", {"b":1}] or [1, 2, 3]. A list of pure objects passes.

Common situations: A JSON array of mixed types where a heterogeneous payload slips in; an array of scalars (strings/numbers) where an array of objects was expected; a flat list from an older API version; an error/status entry mixed into an otherwise-object array.

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/a8363a741a6ca6e0. Report an issue: GitHub.