quarkusio/quarkus · error · IllegalArgumentException
Event#select(Class<U>, Annotation...) cannot be used with ty
Error message
Event#select(Class<U>, Annotation...) cannot be used with type variable parameter
What it means
EventImpl.select(Class<U>, Annotation...) — the CDI Event#select API — rejects a subtype parameter that still contains type variables (e.g. Class<T> where T is a generic type parameter of the enclosing method/class). The CDI spec forbids selecting on unresolved type variables because the resulting event type could not be resolved at runtime, so ArC throws IllegalArgumentException.
Source
Thrown at independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/EventImpl.java:147
@Override
public Notifier<? super T> apply(Class<?> clazz) {
return createNotifier(clazz);
}
});
}
@Override
public Event<T> select(Annotation... qualifiers) {
ArcContainerImpl.instance().registeredQualifiers.verify(qualifiers);
Set<Annotation> mergedQualifiers = new HashSet<>(this.qualifiers);
Collections.addAll(mergedQualifiers, qualifiers);
return new EventImpl<T>(eventType, mergedQualifiers, injectionPoint);
}
@Override
public <U extends T> Event<U> select(Class<U> subtype, Annotation... qualifiers) {
if (Types.containsTypeVariable(subtype)) {
throw new IllegalArgumentException(
"Event#select(Class<U>, Annotation...) cannot be used with type variable parameter");
}
ArcContainerImpl.instance().registeredQualifiers.verify(qualifiers);
Set<Annotation> mergerdQualifiers = new HashSet<>(this.qualifiers);
Collections.addAll(mergerdQualifiers, qualifiers);
return new EventImpl<U>(subtype, mergerdQualifiers, injectionPoint);
}
@Override
public <U extends T> Event<U> select(TypeLiteral<U> subtype, Annotation... qualifiers) {
ArcContainerImpl.instance().registeredQualifiers.verify(qualifiers);
if (Types.containsTypeVariable(subtype.getType())) {
throw new IllegalArgumentException(
"Event#select(TypeLiteral, Annotation...) cannot be used with type variable parameter");
}
Set<Annotation> mergerdQualifiers = new HashSet<>(this.qualifiers);
Collections.addAll(mergerdQualifiers, qualifiers);
return new EventImpl<U>(subtype.getType(), mergerdQualifiers, injectionPoint);View on GitHub (pinned to e1c734241f)
Solutions
- Use the concrete, non-generic class literal in select(), or reify the generic type with a TypeLiteral: event.select(new TypeLiteral<List<String>>() {}).
- Pass the runtime class via a constructor/parameter captured from the concrete subclass (getClass() at a non-generic call site).
- Move the select() call to a non-generic location where the type is fully known.
- If full runtime generic info is needed, use super type tokens (subclass anonymous TypeLiteral) rather than Class<T>.
Example fix
// before
class Publisher<T> {
void fire(T payload) { event.select((Class<T>) payload.getClass()); } // may still contain type vars
}
// after
event.select(new TypeLiteral<MyConcretePayload>() {}); Defensive patterns
Strategy: type-guard
Validate before calling
if (Types.containsTypeVariable(subtype)) {
throw new IllegalArgumentException("select() requires a fully resolved type, got " + subtype);
} Type guard
static <T> boolean isConcreteEventType(Class<T> subtype) {
return !io.quarkus.arc.impl.Types.containsTypeVariable(subtype);
} Try / catch
try {
event.select(subtypeClass);
} catch (IllegalArgumentException e) {
if (!e.getMessage().contains("type variable parameter")) throw e;
// fall back to a TypeLiteral-based select with a resolved type
} Prevention
- Prefer TypeLiteral (super type token) over Class<T> when selecting generic event subtypes.
- Avoid calling Event.select from generic classes/methods; resolve the type first.
- Capture concrete classes at non-generic call sites (e.g. getClass() in concrete subclasses).
When it happens
Trigger: Inside a generic class/method, calling event.select(SomeGenericClass.class) where SomeGenericClass is itself generic and the class literal (e.g. T.class or ResultWrapper.class with T unresolved) contains type variables; the other select(TypeLiteral) overload throws its own analogous error.
Common situations: Generic helper/service classes wrapping CDI events where developers pass Class<T> fields obtained from generic APIs; refactoring an event publisher into a generic base class; Java's type erasure making Class<T> literals retain unresolved type variables.
Related errors
- Producer method return type is a parameterized type with a t
- Event injection point can never be raw type - please specify
- The given type is a type variable: " + requiredType
- The runtime type of the event object contains a type variabl
- Event type contains a type variable: ${specifiedType}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/a289bd3ae09a72bd.
Report an issue: GitHub.