{"record":{"id":"610f77d9f2b43c86","repo":"FasterXML/jackson-databind","slug":"cannot-construct-enummap-generic-key-type-not-a","errorCode":null,"errorMessage":"Cannot construct EnumMap; generic (key) type not available","messagePattern":"Cannot construct EnumMap; generic \\(key\\) type not available","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/tools/jackson/databind/deser/BasicDeserializerFactory.java","lineNumber":925,"sourceCode":"            Class<?> mapClass = type.getRawClass();\n            // [databind#1853]: Map `Map<ENUM,x>` to `EnumMap<ENUM,x>`\n            if ((mapClass == Map.class) && keyType.isEnumType()) {\n                mapClass = EnumMap.class;\n                type = (MapType) config.getTypeFactory().constructSpecializedType(type, mapClass);\n//                type = (MapType) config.getTypeFactory().constructMapType(mapClass, keyType, contentType);\n            }\n            if (EnumMap.class.isAssignableFrom(mapClass)) {\n                ValueInstantiator inst;\n\n                // 06-Mar-2017, tatu: Should only need to check ValueInstantiator for\n                //    custom sub-classes, see [databind#1544]\n                if (mapClass == EnumMap.class) {\n                    inst = null;\n                } else {\n                    inst = findValueInstantiator(ctxt, beanDescRef);\n                }\n                if (!keyType.isEnumImplType()) {\n                    throw new IllegalArgumentException(\"Cannot construct EnumMap; generic (key) type not available\");\n                }\n                deser = new EnumMapDeserializer(type, inst, null,\n                        contentDeser, contentTypeDeser, null);\n            }\n\n            // Otherwise, generic handler works ok.\n\n            /* But there is one more twist: if we are being asked to instantiate\n             * an interface or abstract Map, we need to either find something\n             * that implements the thing, or give up.\n             *\n             * Note that we do NOT try to guess based on secondary interfaces\n             * here; that would probably not work correctly since casts would\n             * fail later on (as the primary type is not the interface we'd\n             * be implementing)\n             */\n            if (deser == null) {\n                if (type.isInterface() || type.isAbstract()) {","sourceCodeStart":907,"sourceCodeEnd":943,"githubUrl":"https://github.com/FasterXML/jackson-databind/blob/87876ca5c0569b4933aec2d30d6225e4b9ba3a43/src/main/java/tools/jackson/databind/deser/BasicDeserializerFactory.java#L907-L943","documentation":"Thrown by BasicDeserializerFactory when constructing an EnumMap (or a Map<Enum,X> specialized to EnumMap) and the enum key type is not resolvable at runtime (keyType.isEnumImplType() is false). EnumMap requires a concrete enum class to be instantiated; without generic type information Jackson cannot supply it.","triggerScenarios":"Deserializing into a raw EnumMap, an EnumMap field whose generic key type is erased/bound to a non-enum type, or a Map<K,V> where K is an enum type variable that cannot be reified. Also when type erasure or a TypeFactory miscalculation leaves the key type as a placeholder.","commonSituations":"Using a raw EnumMap field/parameter without generics; deserializing into a generic type whose enum key is supplied via a TypeVariable that never gets bound; subclassing EnumMap without preserving generics; converting from Object.class or Map.class into EnumMap.","solutions":["Provide a fully parameterized type using TypeReference (e.g. new TypeReference<EnumMap<MyEnum,String>>(){}) or constructType with the enum class, so the enum key is reifiable.","Declare the target field/parameter with explicit generic key type (EnumMap<MyEnum, V>), not raw EnumMap.","If the key type is dynamic, build a JavaType via TypeFactory.constructMapType(EnumMap.class, TypeFactory.constructType(enumClass), valueType)."],"exampleFix":"// before: raw type, key enum lost\nEnumMap map = mapper.readValue(json, EnumMap.class);\n\n// after: fully parameterized\nEnumMap<MyEnum,String> map = mapper.readValue(\n    json, new TypeReference<EnumMap<MyEnum,String>>(){});","handlingStrategy":"validation","validationCode":"JavaType type = mapper.getTypeFactory().constructType(new TypeReference<EnumMap<MyEnum,String>>(){});\nif (!type.getKeyType().isEnumImplType()) {\n    throw new IllegalStateException(\"EnumMap key type not an enum: \" + type.getKeyType());\n}\nmapper.readValue(json, type);","typeGuard":"boolean hasEnumKey(JavaType t) {\n    return t.isMapLikeType() && t.getKeyType().isEnumImplType();\n}","tryCatchPattern":null,"preventionTips":["Always parameterize EnumMap fields/parameters with a concrete enum key.","Use TypeReference or constructMapType to supply erased generics.","Avoid raw EnumMap or Map.class targets for enum-keyed maps."],"tags":["jackson","deserialization","enum","enummap","generics","type-erasure"],"backgroundTag":null,"analyzedSha":"87876ca5c0569b4933aec2d30d6225e4b9ba3a43","analyzedAt":"2026-08-11T12:55:24.033Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}