apache/dubbo · error · IllegalArgumentException
`name` filed should be string!
Error message
`name` filed should be string!
What it means
When PojoUtils.realize encounters a Map representing an enum type, it extracts the 'name' key to reconstruct the enum constant via Enum.valueOf. If the value associated with 'name' is non-null but not a String (e.g. an Integer or another Map), Enum.valueOf cannot be called and an IllegalArgumentException is thrown.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java:472
if (pojo instanceof Map<?, ?> && type != null) {
Object className = ((Map<Object, Object>) pojo).get("class");
if (className instanceof String) {
if (!CLASS_NOT_FOUND_CACHE.containsKey(className)) {
try {
type = DefaultSerializeClassChecker.getInstance()
.loadClass(ClassUtils.getClassLoader(), (String) className);
} catch (ClassNotFoundException e) {
CLASS_NOT_FOUND_CACHE.put((String) className, NOT_FOUND_VALUE);
}
}
}
// special logic for enum
if (type.isEnum()) {
Object name = ((Map<Object, Object>) pojo).get("name");
if (name != null) {
if (!(name instanceof String)) {
throw new IllegalArgumentException("`name` filed should be string!");
} else {
return Enum.valueOf((Class<Enum>) type, (String) name);
}
}
}
Map<Object, Object> map;
// when return type is not the subclass of return type from the signature and not an interface
if (!type.isInterface() && !type.isAssignableFrom(pojo.getClass())) {
try {
map = (Map<Object, Object>) type.getDeclaredConstructor().newInstance();
Map<Object, Object> mapPojo = (Map<Object, Object>) pojo;
map.putAll(mapPojo);
if (GENERIC_WITH_CLZ) {
map.remove("class");
}
} catch (Exception e) {
// ignore error
map = (Map<Object, Object>) pojo;View on GitHub (pinned to 3a3043227f)
Solutions
- Ensure the generic representation of an enum always uses a String value for the 'name' key matching an actual enum constant name.
- If the source sends ordinals, convert them to the enum constant name before passing to realize.
- On the consumer side, verify the serialization framework encodes enums as their name string, not ordinal.
- For custom Map construction, explicitly cast: map.put("name", enumValue.name()).
Example fix
// before
Map<String, Object> map = new HashMap<>();
map.put("name", 1); // ordinal — throws
MyEnum result = (MyEnum) PojoUtils.realize(map, MyEnum.class);
// after
map.put("name", MyEnum.ACTIVE.name()); // String constant name Defensive patterns
Strategy: validation
Validate before calling
// Validate enum 'name' field is a String before calling realize
if (type.isEnum() && pojo instanceof Map) {
Object nameVal = ((Map<?, ?>) pojo).get("name");
if (nameVal != null && !(nameVal instanceof String)) {
throw new IllegalArgumentException(
"Enum 'name' must be String, got " + nameVal.getClass());
}
}
PojoUtils.realize(pojo, type); Type guard
// Type guard for enum map representations
static boolean isValidEnumMap(Object pojo, Class<?> type) {
if (!type.isEnum() || !(pojo instanceof Map)) return true;
Object name = ((Map<?, ?>) pojo).get("name");
return name == null || name instanceof String;
} Prevention
- When constructing generic Maps for enums, always use enumConstant.name() as the 'name' value.
- For non-Java consumers, document that enum fields must be sent as their String name, not ordinal.
- Validate incoming Maps from non-Java clients before passing to realize.
When it happens
Trigger: Calling PojoUtils.realize on a Map that targets an enum class, where the 'name' entry is a non-String type. This happens during generic RPC deserialization when the wire format (e.g. a custom JSON parser or a non-Java client) sends the enum name as a numeric ordinal or a structured object instead of a plain string.
Common situations: A non-Java consumer (Python, Go, Node.js) calling a Dubbo service via generic invocation that sends an enum as {"name": 1} (ordinal) instead of {"name": "ACTIVE"}. Also a misconfigured serializer or a manual Map construction where the 'name' key was set to the wrong type.
Related errors
- Failed to set pojo ${dest.getClass().getSimpleName()} proper
- Failed to set field ${name} of pojo ${dest.getClass().getNam
- Illegal constructor: ${cls.getName()}
- The instance is not a enum wrapper
- '${key}' doesn't map to a Integer object
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/fcc3d396662be17e.
Report an issue: GitHub.