quarkusio/quarkus · error · IllegalArgumentException
The given type is a type variable: " + requiredType
Error message
The given type is a type variable: " + requiredType
What it means
ArcContainerImpl.getBeans() rejects TypeVariable required types with IllegalArgumentException. The CDI spec requires the given type in BeanManager.getBeans() to be a concrete type; a type variable (e.g. T) carries no resolvable information. Arc fails fast instead of returning an empty/meaningless set.
Source
Thrown at independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java:608
@SuppressWarnings("unchecked")
private <T> InjectableBean<T> getBean(Type requiredType, Annotation... qualifiers) {
if (qualifiers == null || qualifiers.length == 0) {
qualifiers = new Annotation[] { Default.Literal.INSTANCE };
} else {
registeredQualifiers.verify(qualifiers);
}
Resolvable resolvable = new Resolvable(requiredType, qualifiers);
Set<InjectableBean<?>> resolvedBeans = resolved.getValue(resolvable);
if (resolvedBeans.isEmpty()) {
scanRemovedBeans(resolvable);
}
return resolvedBeans.size() != 1 ? null : (InjectableBean<T>) resolvedBeans.iterator().next();
}
Set<Bean<?>> getBeans(Type requiredType, Annotation... qualifiers) {
if (requiredType instanceof TypeVariable) {
throw new IllegalArgumentException("The given type is a type variable: " + requiredType);
}
if (qualifiers == null || qualifiers.length == 0) {
qualifiers = new Annotation[] { Default.Literal.INSTANCE };
} else {
registeredQualifiers.verify(qualifiers);
}
// This method does not cache the results
return Set.of(getMatchingBeans(new Resolvable(requiredType, qualifiers)).toArray(new Bean<?>[] {}));
}
Set<Bean<?>> getBeans(String name) {
// This method does not cache the results
return new HashSet<>(getMatchingBeans(name));
}
boolean isScope(Class<? extends Annotation> annotationType) {
if (annotationType.isAnnotationPresent(Scope.class) || annotationType.isAnnotationPresent(NormalScope.class)) {
return true;View on GitHub (pinned to e1c734241f)
Solutions
- Pass the concrete resolved type (e.g. new ParameterizedType with actual type arguments, or the raw class) instead of the TypeVariable
- Capture the generic type via an anonymous subclass (TypeLiteral<T>() {}) and pass its type
- Add a runtime guard in your helper rejecting TypeVariable inputs before calling getBeans
Example fix
// before
<T> void lookup() {
container.getBeans(/* T is a TypeVariable */ currentType);
}
// after
Type type = new TypeLiteral<List<String>>() {}.getType();
container.getBeans(type, Any.Literal.INSTANCE); Defensive patterns
Strategy: validation
Validate before calling
if (requiredType instanceof TypeVariable) {
throw new IllegalArgumentException("Resolve to a concrete type first: " + requiredType);
}
Set<Bean<?>> beans = Arc.container().getBeans(requiredType, qualifiers); Type guard
boolean isConcrete(Type t) {
return !(t instanceof TypeVariable)
&& !(t instanceof WildcardType)
&& !(t instanceof GenericArrayType);
} Try / catch
try {
beans = container.getBeans(type, quals);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("type variable")) {
beans = container.getBeans(rawType(type), quals); // fallback to raw type
} else throw e;
} Prevention
- Never pass raw generic method parameters (T) into bean lookup APIs
- Use TypeLiteral/ParameterizedType anonymous subclasses to capture generic types
- In generic helpers, require a Class<T> or Type argument instead of relying on T
When it happens
Trigger: Calling beanManager.getBeans(someTypeVariable, qualifiers) or Arc.container().instance(...)/select(...) where the passed java.lang.reflect.Type is a TypeVariable instance, typically obtained from a generic method parameter or field.getGenericType() on a generic class.
Common situations: Writing generic helper/utility code that does programmatic lookup with T; reflection-based frameworks passing getGenericType() results; generifying a previously concrete lookup after a refactor.
Related errors
- Event#select(Class<U>, Annotation...) cannot be used with ty
- Unable to determine if the '${unsecuredMethod}' method shoul
- Producer method return type is a parameterized type with a t
- InterceptionProxy parameter must be a parameterized type: ${
- Producer field type is a parameterized type with a type vari
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/4026b078bca3e41d.
Report an issue: GitHub.