quarkusio/quarkus · error · IllegalArgumentException
The set of bean types must not be empty
Error message
The set of bean types must not be empty
What it means
resolveDecorators requires a non-empty set of bean types to match decorators against. Passing a null or empty Set gives decorators nothing to compare assignability with, so Arc throws IllegalArgumentException. Qualifiers default to @Default when omitted.
Source
Thrown at independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java:927
Set<Annotation> transitive = registeredInterceptorBindings.getTransitive(binding.annotationType());
if (transitive != null) {
bindings.addAll(transitive);
}
}
for (InjectableInterceptor<?> interceptor : this.interceptors) {
if (interceptor.intercepts(type) && hasAllInterceptionBindings(interceptor, bindings)) {
interceptors.add(interceptor);
}
}
return interceptors;
}
List<Decorator<?>> resolveDecorators(Set<Type> types, Annotation... qualifiers) {
if (decorators.isEmpty()) {
return Collections.emptyList();
}
if (Objects.requireNonNull(types).isEmpty()) {
throw new IllegalArgumentException("The set of bean types must not be empty");
}
if (qualifiers == null || qualifiers.length == 0) {
qualifiers = new Annotation[] { Default.Literal.INSTANCE };
} else {
registeredQualifiers.verify(qualifiers);
}
List<Decorator<?>> decorators = new ArrayList<>();
for (InjectableDecorator<?> decorator : this.decorators) {
if (decoratorMatches(decorator.getDelegateType(), decorator.getDelegateQualifiers(), types, Set.of(qualifiers))) {
decorators.add(decorator);
}
}
return decorators;
}
private boolean hasAllInterceptionBindings(InjectableInterceptor<?> interceptor, Iterable<Annotation> bindings) {
// The method or constructor has all the interceptor bindings of the interceptor
for (Annotation binding : interceptor.getInterceptorBindings()) {View on GitHub (pinned to e1c734241f)
Solutions
- Populate the set with at least one Type (the bean class or interface) before calling
- Null/empty-check the types set in your calling code and short-circuit to an empty decorator list
- If deriving types from a bean, use bean.getTypes() which never returns empty for valid beans
Example fix
// before manager.resolveDecorators(Set.of(), Default.Literal.INSTANCE); // after manager.resolveDecorators(Set.of(MyService.class), Default.Literal.INSTANCE);
Defensive patterns
Strategy: validation
Validate before calling
Objects.requireNonNull(types, "types");
if (types.isEmpty()) {
return List.of(); // or throw with a clearer message
}
List<Decorator<?>> decorators = bm.resolveDecorators(types, qualifiers); Try / catch
try {
return bm.resolveDecorators(types, quals);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("bean types must not be empty")) {
return List.of();
} else throw e;
} Prevention
- Source the types set from bean.getTypes() rather than computing it manually
- Assert non-empty types before any decorator resolution call
- Add a regression test when refactoring code that builds type sets
When it happens
Trigger: Calling beanManager.resolveDecorators(Collections.emptySet(), qualifiers) or resolveDecorators(null, ...); building the types set from an object whose getTypes() returned empty due to an earlier resolution failure.
Common situations: Extension/tooling code computing decorator matches dynamically; a refactor that changed how the bean types set is assembled and accidentally yields an empty set.
Related errors
- Contextual parameter must not be null
- Not an annotation:
- No interceptor bindings
- Type ${beanType} is not a bean type of ${bean}; its bean typ
- Arguments must be instances of ${InjectableBean.class} and $
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/b54a731319dea485.
Report an issue: GitHub.