google/gson · error · JsonIOException
Invalid EnumMap type: {type}
Error message
Invalid EnumMap type: {type} What it means
The EnumMap factory requires a ParameterizedType whose first argument is a Class (the key enum type). If the key argument is itself generic/parameterized/wildcard, the enum class cannot be determined and JsonIOException is thrown.
Source
Thrown at gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java:206
throw new JsonIOException("Invalid EnumSet type: " + type);
}
} else {
throw new JsonIOException("Invalid EnumSet type: " + type);
}
};
}
// Only support creation of EnumMap, but not of custom subtypes; for them type parameters
// and constructor parameter might have completely different meaning
else if (rawType == EnumMap.class) {
return () -> {
if (type instanceof ParameterizedType) {
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
if (elementType instanceof Class) {
@SuppressWarnings({"unchecked", "rawtypes"})
T map = (T) new EnumMap((Class) elementType);
return map;
} else {
throw new JsonIOException("Invalid EnumMap type: " + type);
}
} else {
throw new JsonIOException("Invalid EnumMap type: " + type);
}
};
}
return null;
}
private static <T> ObjectConstructor<T> newDefaultConstructor(
Class<? super T> rawType, FilterResult filterResult) {
// Cannot invoke constructor of abstract class
if (Modifier.isAbstract(rawType.getModifiers())) {
return null;
}
Constructor<? super T> constructor;View on GitHub (pinned to 8b8628c656)
Solutions
- Use a concrete enum key: EnumMap<MyEnum, String>.
- Build an explicit TypeToken: new TypeToken<EnumMap<MyEnum, String>>(){}.
- Register an InstanceCreator<EnumMap<MyEnum, V>>.
- Avoid wildcard/type-variable keys on EnumMap fields.
Example fix
// before EnumMap<? extends Color, Integer> counts; // after EnumMap<Color, Integer> counts;
Defensive patterns
Strategy: validation
Validate before calling
if (type instanceof ParameterizedType
&& ((ParameterizedType) type).getActualTypeArguments()[0] instanceof Class) {
// safe EnumMap construction
}
Type guard
boolean isConcreteEnumMapType(Type t) {
if (!(t instanceof ParameterizedType)) return false;
Type k = ((ParameterizedType) t).getActualTypeArguments()[0];
return k instanceof Class && ((Class<?>) k).isEnum();
}
Try / catch
try {
return gson.fromJson(json, type);
} catch (JsonIOException ex) {
if (ex.getMessage().startsWith("Invalid EnumMap type")) {
// register InstanceCreator and retry
}
throw ex;
}
Prevention
- Use concrete enum keys on EnumMap fields.
- Build explicit TypeToken<EnumMap<MyEnum, V>>(){}.
- Register an InstanceCreator for generic map utilities.
When it happens
Trigger: Field declared EnumMap<MyEnum<?>, V>, EnumMap<K, V> with K a type variable, or a TypeToken losing the concrete enum key class; reflective construction where the key type is captured generically.
Common situations: Generic map utilities; wildcard key bounds; frameworks binding EnumMap<K,V> generically.
Related errors
- Invalid EnumSet type: {type}
- Failed to invoke constructor '{constructor}' with no args
- Unable to create instance of {rawType}. Registering an Insta
- Expected a Class, ParameterizedType, or GenericArrayType, bu
- {contextRawType} is not the same as or a subtype of {superty
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/db66c5aa19e6f324.json.
Report an issue: GitHub.