json-path/JsonPath · error · MappingException
JSON array cannot be mapped to " + className
Error message
JSON array cannot be mapped to " + className
What it means
When mapping a JSON array, newCollectionOfType() instantiates the requested Collection target type: concrete classes need a public no-arg constructor, and known interfaces (List, Set, Queue) are mapped to LinkedList/LinkedHashSet. If the target type is not a Collection subtype (e.g. Map or a POJO) or is an unrecognized Collection interface such as SortedSet or Deque, it throws MappingException because a JSON array cannot be materialized into that type.
Source
Thrown at json-path/src/main/java/com/jayway/jsonpath/spi/mapper/JakartaMappingProvider.java:310
* @return instance of collection type identified by the argument
* @throws MappingException on a type that cannot be safely instantiated
*/
private Collection<Object> newCollectionOfType(Class<?> collectionType) throws MappingException {
if (Collection.class.isAssignableFrom(collectionType)) {
if (!collectionType.isInterface()) {
@SuppressWarnings("unchecked")
Collection<Object> coll = (Collection<Object>) newNoArgInstance(collectionType);
return coll;
} else if (List.class.isAssignableFrom(collectionType)) {
return new java.util.LinkedList<Object>();
} else if (Set.class.isAssignableFrom(collectionType)) {
return new java.util.LinkedHashSet<Object>();
} else if (Queue.class.isAssignableFrom(collectionType)) {
return new java.util.LinkedList<Object>();
}
}
String className = collectionType.getSimpleName();
throw new MappingException("JSON array cannot be mapped to " + className);
}
/**
* Lists all publicly accessible constructors for the {@code Class}
* identified by the argument, including any constructors inherited
* from superclasses, and uses a no-args constructor, if available,
* to create a new instance of the class. If argument is interface,
* this method returns {@code null}.
*
* @param targetType class type to create instance of
* @return an instance of the class represented by the argument
* @throws MappingException if no-arg public constructor is not there
*/
private Object newNoArgInstance(Class<?> targetType) throws MappingException {
if (targetType.isInterface()) {
return null;
} else {
for (Constructor<?> ctr : targetType.getConstructors()) {
View on GitHub (pinned to 62a4c9f0f6)
Solutions
- Map the JSON array into a supported target: List.class, Set.class, Queue.class, or a concrete Collection class with a public no-arg constructor (e.g. ArrayList.class).
- If you need Deque/SortedSet/etc., read into a supported interface first and convert: new java.util.TreeSet<>(jsonPath.read(path, List.class)).
- Ensure the element type is conveyed via TypeRef, e.g. new TypeRef<List<Book>>(){}, so collection creation and element mapping both work.
- If the target should be a single object rather than a collection, the JSON at that path must be an object, not an array — fix the path or the expected type.
Example fix
// before
List<Book> books = jsonPath.read("$.store.book", SortedSet.class); // MappingException
// after
List<Book> books = jsonPath.read("$.store.book", new TypeRef<List<Book>>() {});
SortedSet<Book> sorted = new TreeSet<>(books); Defensive patterns
Strategy: validation
Validate before calling
static boolean mappableArrayTarget(Class<?> t) {
return java.util.Collection.class.isAssignableFrom(t)
&& (!t.isInterface() || java.util.List.class.isAssignableFrom(t)
|| java.util.Set.class.isAssignableFrom(t)
|| java.util.Queue.class.isAssignableFrom(t));
} Try / catch
try {
return jsonPath.read(path, targetType);
} catch (MappingException e) {
return new ArrayList<>(jsonPath.read(path, List.class));
} Prevention
- Only request List, Set, Queue, or concrete collection classes with public no-arg constructors as array targets.
- Prefer TypeRef<List<T>> over custom collection types.
- Check that the path actually points to a JSON array when a collection type is requested.
When it happens
Trigger: read("$.items", SomeNonCollectionClass.class) where the path points to a JSON array and the class is not Collection-assignable, or requesting a Collection interface not handled by the if/else chain (e.g. SortedSet.class, Deque.class, Iterable.class), including via TypeRef/ParameterizedType whose raw type falls through.
Common situations: Typos in the target class; assuming all java.util Collection interfaces are supported (only List/Set/Queue branches exist, so SortedSet/Deque fail); trying to map an array directly into Map.class or a bean class; using a custom collection type without a no-arg constructor.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Cannot map JSON element to " + typeName
- Cannot create JSON iterator for " + value
- Can only rename properties in a map
- Can only add to an array
- Can only add properties to a map
AI-assisted analysis of json-path/JsonPath@62a4c9f0f6 (2026-09-11).
Data as JSON: /api/errors/af00d6c5912e2251.
Report an issue: GitHub.