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
- Validate or filter the list before calling checkObjectList: rawList.stream().filter(Map.class::isInstance).map(m -> (Map<String,?>) m).collect(toList()).
- If the schema requires all-object entries, reject/fix the upstream payload that produced a scalar entry.
- Use getList (untyped) if you must tolerate heterogeneous entries, then handle each element by type.
- 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
- Filter a list to Map entries before calling checkObjectList when heterogeneity is possible.
- Validate array element types against the schema at trust boundaries.
- Use getList (untyped) and per-element handling if mixed types are legitimate.
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
- value '%s' for idx %d in '%s' is not string
- value '%s' for key '%s' in '%s' is not List
- value '%s' for key '%s' in '%s' is not object
- value '%s' for key '%s' in '%s' is not String
- value '%s' for key '%s' in '%s' is not a number
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/a8363a741a6ca6e0.
Report an issue: GitHub.