gradle/gradle · error · UnsupportedOperationException
Cannot convert a Collection to type %s.
Error message
Cannot convert a Collection to type %s.
What it means
ProtocolToModelAdapter copies provider-side tooling model data into the client's view interfaces. CollectionMapper.createEmptyCollection can only instantiate ArrayList, LinkedHashSet, or TreeSet (plus DomainObjectSet); when the view interface's collection return type accepts none of those (Queue, Deque, Stack, a custom collection class), it throws UnsupportedOperationException naming the unsupported type.
Source
Thrown at platforms/ide/tooling-api/src/main/java/org/gradle/tooling/internal/adapter/CollectionMapper.java:43
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
class CollectionMapper {
Collection<Object> createEmptyCollection(Class<?> collectionType) {
if (collectionType.equals(DomainObjectSet.class)) {
return new ArrayList<Object>();
}
if (collectionType.isAssignableFrom(ArrayList.class)) {
return new ArrayList<Object>();
}
if (collectionType.isAssignableFrom(LinkedHashSet.class)) {
return new LinkedHashSet<Object>();
}
if (collectionType.isAssignableFrom(TreeSet.class)) {
return new TreeSet<Object>();
}
throw new UnsupportedOperationException(String.format("Cannot convert a Collection to type %s.", collectionType.getName()));
}
Map<Object, Object> createEmptyMap(Class<?> mapType) {
if (mapType.isAssignableFrom(LinkedHashMap.class)) {
return new LinkedHashMap<Object, Object>();
}
if (mapType.isAssignableFrom(TreeMap.class)) {
return new TreeMap<Object, Object>();
}
throw new UnsupportedOperationException(String.format("Cannot convert a Map to type %s.", mapType.getName()));
}
}
View on GitHub (pinned to 534f27719b)
Solutions
- Change the model getter to List, Set, or SortedSet (the adapter maps these to ArrayList/LinkedHashSet/TreeSet)
- Fetch the standard type and convert client-side: new ArrayDeque<>(model.getHistory())
- Keep tooling model interfaces limited to JDK-standard collection abstractions
Example fix
// before
public interface MyToolingModel {
Queue<String> getPendingOperations(); // adapter cannot build a Queue -> throws
}
// after
public interface MyToolingModel {
List<String> getPendingOperations();
}
// client converts if needed: new ArrayDeque<>(model.getPendingOperations()) Defensive patterns
Strategy: validation
Validate before calling
// reject unsupported collection types before publishing a model interface
private static final Set<Class<?>> SUPPORTED = Set.of(
Collection.class, List.class, Set.class, SortedSet.class, DomainObjectSet.class);
static void checkCollectionType(Class<?> type) {
if (!SUPPORTED.contains(type)) {
throw new IllegalArgumentException("Unsupported tooling-model collection type: " + type.getName());
}
} Type guard
static boolean isSupportedCollectionType(Class<?> type) {
return Collection.class.equals(type) || List.class.equals(type) || Set.class.equals(type)
|| SortedSet.class.equals(type) || DomainObjectSet.class.equals(type);
} Prevention
- Declare tooling model getters as List/Set/SortedSet only; never Queue, Deque, or custom collection classes
- Convert to exotic collection types client-side after fetching the model
- Add a build-time check or review rule for model interface return types
When it happens
Trigger: Declaring a custom tooling model interface with a getter returning an unsupported collection type, e.g. Queue<String> getHistory() or MyCustomList getItems(), then fetching that model from a ProjectConnection.
Common situations: Custom tooling models in plugins consumed by IDEs or CI where the author used an exotic collection type; refactor from List to a domain-specific collection class; model interfaces generated with strict types.
Related errors
- Cannot convert a Map to type %s.
- Illegal null value provided in this collection: {}
- Continuous build does not work when file system watching is
- No model type or tasks specified.
- Cannot run tasks and fetch the build environment model.
AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22).
Data as JSON: /api/errors/57de66204eda8556.
Report an issue: GitHub.