FasterXML/jackson-databind · error · IllegalArgumentException
Cannot deserialize Singleton container from "+size+" entries
Error message
Cannot deserialize Singleton container from "+size+" entries
What it means
JavaUtilCollectionsDeserializers uses a Converter to rebuild values whose declared type is one of java.util.Collections' singleton* return types (SingletonList, SingletonSet, SingletonMap). The converter _checkSingleton enforces that the incoming collection has exactly one element, because a singleton container cannot hold more (or fewer) than one. Anything else throws IllegalArgumentException.
Solutions
- Change the target type to a plain List/Set/Map (e.g. ArrayList, HashSet, HashMap) so multiple entries are accepted.
- Fix the JSON payload so it contains exactly one entry when the target must remain a singleton type.
- If the singleton type was inferred unintentionally, declare the field as List<T> rather than letting the runtime singleton type leak into serialization metadata.
Example fix
// before
public class Config {
public List<String> names = Collections.singletonList("default");
}
// JSON: {"names":["a","b"]} -> throws
// after
public class Config {
public List<String> names = new ArrayList<>(List.of("default"));
} Defensive patterns
Strategy: validation
Validate before calling
// Do not use Collections.singleton* as field runtime types for mutable data.
if (field.getType().isAssignableFrom(Collections.singletonList("").getClass())) {
throw new IllegalStateException("Refusing singleton list as a mutable target");
} Prevention
- Declare collection fields as List/Set/Map interfaces backed by ArrayList/HashSet/HashMap, not by Collections.singleton*.
- Validate JSON payloads for singleton-typed targets contain exactly one entry before deserialization.
- Avoid reusing singleton instances as deserialize targets in round-trip tests.
When it happens
Trigger: A field/parameter whose runtime type is Collections.singletonList(...), Collections.singleton(...), or Collections.singletonMap(...), and the JSON being deserialized contains zero or two-or-more entries; serializing a singleton, mutating the JSON to add entries, then deserializing back.
Common situations: Using Collections.singletonList(x) as a constant and then feeding JSON with multiple values into a round-trip; APIs that expose List<T> but assign a singleton list and let Jackson infer the concrete singleton type; tests that hand-craft JSON payloads against singleton-typed fixtures.
Related errors
- Trying to resolve a forward reference with id
- AnnotationIntrospector returned Class
- AnnotationIntrospector returned Converter definition of type
- Argument `allowedSchemes` must not be null
- Missing generic type information for "+type
AI-assisted analysis of FasterXML/jackson-databind@87876ca5c0 (2026-08-11).
Data as JSON: /api/errors/4de4420675aa9009.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/tools/jackson/databind/deser/jdk/JavaUtilCollectionsDeserializers.java:266
return value;
}
}
@Override
public JavaType getInputType(TypeFactory typeFactory) {
return _inputType;
}
@Override
public JavaType getOutputType(TypeFactory typeFactory) {
// we don't actually care, so:
return _inputType;
}
private void _checkSingleton(int size) {
if (size != 1) {
// not the best error ever but... has to do
throw new IllegalArgumentException("Cannot deserialize Singleton container from "+size+" entries");
}
}
}
}
View on GitHub (pinned to 87876ca5c0)