FasterXML/jackson-databind · error · IllegalArgumentException

Missing generic type information for "+type

Error message

Missing generic type information for "+type

What it means

MapEntryDeserializer's constructor requires the JavaType to carry both type parameters of Map.Entry<K,V> (containedTypeCount()==2). A raw or partially parameterized Map.Entry type cannot be deserialized because the key and value deserializers cannot be located. The check throws IllegalArgumentException during deserializer construction.

Solutions

  1. Always deserialize Map.Entry with a TypeReference: new TypeReference<Map.Entry<String,Integer>>(){}.
  2. Declare the target field/parameter as Map.Entry<K,V> with both type arguments present.
  3. If generics are genuinely unknown, deserialize to a concrete pair type (e.g. AbstractMap.SimpleEntry) or to JsonNode and convert afterwards.
  4. Audit TypeReference usage to ensure the anonymous subclass captures the bindings (do not use a generic helper method that erases them).

Example fix

// before
Map.Entry<String,Integer> e = mapper.readValue(json, Map.Entry.class); // raw

// after
Map.Entry<String,Integer> e = mapper.readValue(json,
    new TypeReference<Map.Entry<String,Integer>>(){});
Defensive patterns

Strategy: type-guard

Validate before calling

JavaType t = mapper.constructType(targetClass);
if (t.isTypeOrSubTypeOf(Map.Entry.class) && t.containedTypeCount() < 2) {
    throw new IllegalArgumentException(
        "Cannot deserialize raw Map.Entry; provide generics via TypeReference");
}

Type guard

boolean isFullyParameterizedEntry(JavaType t) {
    return t != null
        && t.isTypeOrSubTypeOf(Map.Entry.class)
        && t.containedTypeCount() == 2;
}

Prevention

When it happens

Trigger: Passing Map.Entry.class (raw) to readValue or a TypeReference that does not capture both generics; a field of type Map.Entry without type arguments; a TypeFactory misconfiguration that drops generic info before deserializer lookup.

Common situations: Using mapper.readValue(json, Map.Entry.class) directly; reflection-based code that erases generics; legacy APIs returning raw Map.Entry; Kotlin/Scala interop where generic signatures are not preserved at the call site.

Related errors


AI-assisted analysis of FasterXML/jackson-databind@87876ca5c0 (2026-08-11). Data as JSON: /api/errors/c4910dc8a6fe4d57. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/tools/jackson/databind/deser/jdk/MapEntryDeserializer.java:61

    /**
     * If value instances have polymorphic type information, this
     * is the type deserializer that can handle it
     */
    protected final TypeDeserializer _valueTypeDeserializer;

    /*
    /**********************************************************************
    /* Life-cycle
    /**********************************************************************
     */

    public MapEntryDeserializer(JavaType type,
            KeyDeserializer keyDeser, ValueDeserializer<Object> valueDeser,
            TypeDeserializer valueTypeDeser)
    {
        super(type);
        if (type.containedTypeCount() != 2) { // sanity check
            throw new IllegalArgumentException("Missing generic type information for "+type);
        }
        _keyDeserializer = keyDeser;
        _valueDeserializer = valueDeser;
        _valueTypeDeserializer = valueTypeDeser;
    }

    protected MapEntryDeserializer(MapEntryDeserializer src,
            KeyDeserializer keyDeser, ValueDeserializer<Object> valueDeser,
            TypeDeserializer valueTypeDeser)
    {
        super(src);
        _keyDeserializer = keyDeser;
        _valueDeserializer = valueDeser;
        _valueTypeDeserializer = valueTypeDeser;
    }

    /**
     * Factory method for constructing initial (non-contextual) instances.

View on GitHub (pinned to 87876ca5c0)