FasterXML/jackson-databind · error · IllegalStateException
Cannot update `Map.Entry` values
Error message
Cannot update `Map.Entry` values
What it means
Thrown by POJOWrappedDeserializer.deserialize(JsonParser, DeserializationContext, Map.Entry result) — the update-in-place overload on the POJO-wrapped variant of MapEntryDeserializer. This variant deserializes Map.Entry from a JSON object with 'key' and 'value' fields (as opposed to a single-entry object). Like the base class, Map.Entry cannot be updated in-place, so it throws IllegalStateException with the message formatted with backtick-quoted Map.Entry.
Source
Thrown at src/main/java/tools/jackson/databind/deser/jdk/MapEntryDeserializer.java:522
}
t = p.nextToken(); // move to next property or END_OBJECT
}
if (t != JsonToken.END_OBJECT) {
ctxt.reportInputMismatch(this,
"Problem deserializing `Map.Entry`; unexpected content after Object value: "
+JsonToken.valueDescFor(t));
}
return new AbstractMap.SimpleEntry<>(key, value);
}
@Override
public Map.Entry<Object,Object> deserialize(JsonParser p, DeserializationContext ctxt,
Map.Entry<Object,Object> result) throws JacksonException
{
throw new IllegalStateException("Cannot update `Map.Entry` values");
}
@Override
public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
TypeDeserializer typeDeserializer)
throws JacksonException
{
// In future could check current token... for now this should be enough:
return typeDeserializer.deserializeTypedFromObject(p, ctxt);
}
// Copied from `ContainerDeserializerBase`
protected <BOGUS> BOGUS wrapAndThrow(DeserializationContext ctxt,
Throwable t, Object ref, String key) throws JacksonException
{
while (t instanceof InvocationTargetException && t.getCause() != null) {
t = t.getCause();
}View on GitHub (pinned to a50c7d2a1d)
Solutions
- Do not use update-in-place APIs with Map.Entry — deserialize fresh each time.
- If POJO-wrapped format is needed, read into a new Map.Entry rather than updating.
- Use a custom POJO with 'key' and 'value' fields if you need both POJO format and update semantics.
- Avoid the three-argument deserialize overload for any Map.Entry variant.
Example fix
// before: update on POJO-wrapped entry
mapper.readerForUpdating(oldEntry).readValue("{\"key\":1,\"value\":2}");
// after: fresh deserialize
Map.Entry<Integer,Integer> e = mapper.readValue("{\"key\":1,\"value\":2}",
new TypeReference<Map.Entry<Integer,Integer>>() {}); Defensive patterns
Strategy: try-catch
Validate before calling
// Detect POJO-wrapped Map.Entry and avoid update paths
if (Map.Entry.class.isAssignableFrom(targetType)) {
// POJOWrappedDeserializer also rejects updates
throw new UnsupportedOperationException(
"Cannot update Map.Entry (POJO-wrapped) — deserialize fresh");
} Type guard
static boolean isUpdatable(Class<?> type) {
return !Map.Entry.class.isAssignableFrom(type);
} Try / catch
try {
mapper.readerForUpdating(oldEntry).readValue("{\"key\":1,\"value\":2}");
} catch (IllegalStateException e) {
if (e.getMessage().contains("Cannot update `Map.Entry`")) {
entry = mapper.readValue(json, entryTypeRef);
}
} Prevention
- Never use update-in-place APIs with Map.Entry regardless of deserialization format.
- Always create fresh Map.Entry instances from JSON.
- Use mutable wrapper POJOs if update semantics are required.
When it happens
Trigger: Calling mapper.readerForUpdating(existingEntry).readValue(json) where the entry uses the POJO-wrapped format (JSON like {"key":...,"value":...}). Any update-path that routes through POJOWrappedDeserializer for a Map.Entry type. Using ObjectReader.updateValue() on a Map.Entry configured for POJO-wrapped shape.
Common situations: Configuring @JsonFormat(shape=ANY) or ACCEPT_CASE_INSENSITIVE_PROPERTIES on a Map.Entry type and then attempting update. Using JsonFormat.Value for Map.Entry to force POJO-wrapped format. Round-tripping through update APIs after switching the entry deserialization format.
Related errors
- Cannot update Map.Entry values
- Missing generic type information for ${type}
- Trying to resolve a forward reference with id [{}] that wasn
- Cannot call withValueDeserializer() on {}
- Cannot pass null property name
AI-assisted analysis of FasterXML/jackson-databind@a50c7d2a1d (2026-08-06).
Data as JSON: /api/errors/779760419e063947.
Report an issue: GitHub.