apache/dubbo · error · IllegalArgumentException
[ServiceDefinitionBuilder] Collection type [{0}] with unexpe
Error message
[ServiceDefinitionBuilder] Collection type [{0}] with unexpected amount of arguments [{1}].<Arrays.toString(actualTypeArgs)> What it means
Thrown by CollectionTypeBuilder.build when a parameterized Collection type does not have exactly one type argument. Dubbo's metadata definition expects collections (List, Set, etc.) to carry a single element type; zero or multiple arguments indicate a malformed or unsupported type and are rejected during service-metadata building.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java:52
@Override
public boolean accept(Class<?> clazz) {
if (clazz == null) {
return false;
}
return Collection.class.isAssignableFrom(clazz);
}
@Override
public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
if (!(type instanceof ParameterizedType)) {
return new TypeDefinition(clazz.getCanonicalName());
}
ParameterizedType parameterizedType = (ParameterizedType) type;
Type[] actualTypeArgs = parameterizedType.getActualTypeArguments();
if (actualTypeArgs == null || actualTypeArgs.length != 1) {
throw new IllegalArgumentException(MessageFormat.format(
"[ServiceDefinitionBuilder] Collection type [{0}] with unexpected amount of arguments [{1}]."
+ Arrays.toString(actualTypeArgs),
type,
actualTypeArgs));
}
String colType = ClassUtils.getCanonicalNameForParameterizedType(parameterizedType);
TypeDefinition td = typeCache.get(colType);
if (td != null) {
return td;
}
td = new TypeDefinition(colType);
typeCache.put(colType, td);
Type actualType = actualTypeArgs[0];
TypeDefinition itemTd = null;
if (actualType instanceof ParameterizedType) {
// Nested collection or map.View on GitHub (pinned to 3a3043227f)
Solutions
- Ensure the service interface uses standard single-element collections (e.g. List<Foo>, Set<Bar>).
- Avoid custom Collection subtypes with multiple type parameters for RPC method signatures.
- Simplify or unwrap exotic nested generic types in the service contract.
Example fix
// before
public interface MyService {
// custom multi-arg collection confuses the builder
MyWeirdMultiTypeContainer<String, Integer> op();
}
// after
public interface MyService {
List<String> op(); // standard single-element collection
} Defensive patterns
Strategy: validation
Validate before calling
// Validate service method collection types have exactly one type arg
for (java.lang.reflect.Method m : serviceInterface.getDeclaredMethods()) {
checkType(m.getGenericReturnType());
for (Type t : m.getGenericParameterTypes()) checkType(t);
}
// helper
void checkType(Type t) {
if (t instanceof ParameterizedType pt
&& Collection.class.isAssignableFrom(
(Class<?>) ((ParameterizedType) t).getRawType())
&& pt.getActualTypeArguments().length != 1) {
throw new IllegalArgumentException("Collection type must have one type arg: " + t);
}
} Type guard
static boolean isWellFormedCollectionType(Type t) {
if (!(t instanceof ParameterizedType pt)) return true;
try {
return Collection.class.isAssignableFrom((Class<?>) pt.getRawType())
? pt.getActualTypeArguments().length == 1
: true;
} catch (Exception e) { return false; }
} Try / catch
try {
// metadata build / service export
serviceRepository.register(serviceInterface);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Collection type")) {
// simplify the offending collection generic in the service contract
}
throw e;
} Prevention
- Use standard single-element collections (List<E>, Set<E>) in RPC signatures.
- Avoid custom multi-type-parameter Collection subtypes in service interfaces.
- Run a metadata-introspection smoke test at build time to catch exotic generics.
When it happens
Trigger: Building service metadata (TypeDefinition) for a service method whose parameter/return type is a parameterized Collection with actualTypeArguments.length != 1. This runs during metadata introspection, e.g. when registering/exposing a service or generating repository metadata.
Common situations: A raw collection type that somehow reports zero type args in a non-standard JVM/library. A custom Collection subtype with unusual generic arity. Bizarre nested generics that defeat the builder's single-arg assumption. JVM/library reflection quirks on synthetic types.
Related errors
- unable to determine bean class from factory's superclass or
- Unrecognized Type: ${fieldType.toString()}
- ${cls.getName()} generic type undefined!
- Can not merge result because missing method [ {merger} ] in
- Can not merge result: {e.getMessage()}
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/61e1388b08fbe5ec.
Report an issue: GitHub.