google/gson · error · JsonIOException
Invalid EnumSet type: {type}
Error message
Invalid EnumSet type: {type} What it means
ConstructorConstructor builds an EnumSet factory only when the type is a ParameterizedType whose first type argument is a Class (the enum element type). If the argument is a ParameterizedType, TypeVariable, WildcardType, etc., it throws JsonIOException with the offending type.
Source
Thrown at gson/src/main/java/com/google/gson/internal/ConstructorConstructor.java:188
return newUnsafeAllocator(rawType);
}
/**
* Creates constructors for special JDK collection types which do not have a public no-args
* constructor.
*/
private static <T> ObjectConstructor<T> newSpecialCollectionConstructor(
Type type, Class<? super T> rawType) {
if (EnumSet.class.isAssignableFrom(rawType)) {
return () -> {
if (type instanceof ParameterizedType) {
Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0];
if (elementType instanceof Class) {
@SuppressWarnings({"unchecked", "rawtypes"})
T set = (T) EnumSet.noneOf((Class) elementType);
return set;
} else {
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);View on GitHub (pinned to 8b8628c656)
Solutions
- Declare the field as EnumSet<MyEnum> with a concrete enum class.
- Build a TypeToken with the concrete enum: new TypeToken<EnumSet<MyEnum>>(){}.
- Register an InstanceCreator<EnumSet> that supplies EnumSet.noneOf(MyEnum.class).
- Avoid wildcards/type variables on EnumSet fields used for deserialization.
Example fix
// before EnumSet<? extends Color> colors; // fails // after EnumSet<Color> colors; // concrete enum type
Defensive patterns
Strategy: validation
Validate before calling
if (type instanceof ParameterizedType
&& ((ParameterizedType) type).getActualTypeArguments()[0] instanceof Class) {
// safe to let Gson construct EnumSet
}
Type guard
boolean isConcreteEnumSetType(Type t) {
return t instanceof ParameterizedType
&& ((ParameterizedType) t).getActualTypeArguments()[0] instanceof Class;
}
Try / catch
try {
return gson.fromJson(json, type);
} catch (JsonIOException ex) {
if (ex.getMessage().startsWith("Invalid EnumSet type")) {
// register InstanceCreator and retry with EnumSet.noneOf(MyEnum.class)
}
throw ex;
}
Prevention
- Declare EnumSet fields with a concrete enum type.
- Build TypeToken<EnumSet<MyEnum>>(){} explicitly.
- Register an InstanceCreator<EnumSet> for generic utilities.
When it happens
Trigger: Deserializing a field declared as EnumSet<? extends MyEnum>, EnumSet<T> with a type variable, or EnumSet with a parameterized element type; reflective construction from generic TypeTokens that lose the concrete enum class.
Common situations: Generic utility classes holding EnumSet<E>; wildcard bounds in API models; incorrectly built TypeToken<EnumSet<...>> where the enum type is erased at capture.
Related errors
- Invalid EnumMap 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/9f452bb2c5f9a061.json.
Report an issue: GitHub.