{"record":{"id":"5ee26272ea2f1ecb","repo":"FasterXML/jackson-databind","slug":"cannot-update-map-entry-values","errorCode":null,"errorMessage":"Cannot update Map.Entry values","messagePattern":"Cannot update Map\\.Entry values","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/main/java/tools/jackson/databind/deser/jdk/MapEntryDeserializer.java","lineNumber":311,"sourceCode":"            if (t == JsonToken.PROPERTY_NAME) { // most likely\n                ctxt.reportInputMismatch(this,\n                        \"Problem binding JSON into Map.Entry: more than one entry in JSON (second field: '%s')\",\n                        p.currentName());\n            } else {\n                // how would this occur?\n                ctxt.reportInputMismatch(this,\n                        \"Problem binding JSON into Map.Entry: unexpected content after JSON Object entry: \"+t);\n            }\n            return null;\n        }\n        return new AbstractMap.SimpleEntry<Object,Object>(key, value);\n    }\n\n    @Override\n    public Map.Entry<Object,Object> deserialize(JsonParser p, DeserializationContext ctxt,\n            Map.Entry<Object,Object> result) throws JacksonException\n    {\n        throw new IllegalStateException(\"Cannot update Map.Entry values\");\n    }\n\n    @Override\n    public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,\n            TypeDeserializer typeDeserializer)\n        throws JacksonException\n    {\n        // In future could check current token... for now this should be enough:\n        return typeDeserializer.deserializeTypedFromObject(p, ctxt);\n    }\n\n    /*\n    /**********************************************************************\n    /* Alternate handlers\n    /**********************************************************************\n     */\n\n    /**","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/FasterXML/jackson-databind/blob/a50c7d2a1d57234ac4adf70dbd88ac90db6436e4/src/main/java/tools/jackson/databind/deser/jdk/MapEntryDeserializer.java#L293-L329","documentation":"Thrown by MapEntryDeserializer.deserialize(JsonParser, DeserializationContext, Map.Entry result) — the three-argument overload used for in-place updates (mapper.readerForUpdating(value).readValue(json)). Map.Entry instances are effectively immutable (their key/value cannot be replaced without creating a new entry), so Jackson cannot perform an update-in-place operation and throws IllegalStateException immediately.","triggerScenarios":"Calling ObjectMapper.readerForUpdating(existingEntry).readValue(json) where existingEntry is a Map.Entry. Any code path that triggers the three-argument deserialize with a non-null Map.Entry result object. Using ObjectReader.updateValue() on a Map.Entry.","commonSituations":"Attempting to use ObjectMapper's value-update API on a type that resolves to Map.Entry. Passing a Map.Entry to a deserialization call expecting in-place mutation. Confusing Map.Entry deserialization (create new) with update (modify existing).","solutions":["Do not use update-in-place APIs (readerForUpdating, updateValue) with Map.Entry — always deserialize fresh.","If you need to modify an entry, deserialize a new Map.Entry and replace the reference.","Use a mutable container (a small POJO or a two-element array) instead of Map.Entry if update semantics are required.","Restructure code to avoid the three-argument deserialize path for Map.Entry types."],"exampleFix":"// before: attempting update-in-place\nmapper.readerForUpdating(oldEntry).readValue(json);\n// after: always deserialize new\nMap.Entry<String,Integer> entry = mapper.readValue(json,\n    new TypeReference<Map.Entry<String,Integer>>() {});","handlingStrategy":"try-catch","validationCode":"// Detect Map.Entry types and avoid update-in-place paths\nif (Map.Entry.class.isAssignableFrom(targetType)) {\n    throw new UnsupportedOperationException(\n        \"Cannot update Map.Entry — deserialize fresh instead\");\n}","typeGuard":"static boolean isUpdatable(Class<?> type) {\n    return !Map.Entry.class.isAssignableFrom(type);\n}","tryCatchPattern":"try {\n    mapper.readerForUpdating(oldEntry).readValue(json);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"Cannot update Map.Entry\")) {\n        // Deserialize fresh instead\n        entry = mapper.readValue(json, entryTypeRef);\n    }\n}","preventionTips":["Never use readerForUpdating or updateValue with Map.Entry types.","Always deserialize Map.Entry instances fresh from JSON.","Use mutable POJOs if in-place update semantics are needed."],"tags":["jackson","deserialization","map-entry","update-in-place","immutable"],"analyzedSha":"a50c7d2a1d57234ac4adf70dbd88ac90db6436e4","analyzedAt":"2026-08-06T20:31:51.404Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}