quarkusio/quarkus · error · IllegalArgumentException
Event type contains a type variable: ${specifiedType}
Error message
Event type contains a type variable: ${specifiedType} What it means
The CDI Event.isMatching / event type check rejects a specifiedType containing type variables with IllegalArgumentException, since matching a type variable against an observed event type is undefined per spec. Qualifiers on both sides are verified as registered before the comparison proceeds.
Source
Thrown at independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/BeanManagerImpl.java:364
}
if (!BeanTypeAssignabilityRules.instance().matches(requiredType, legalBeanTypes)) {
return false;
}
return ArcContainerImpl.instance().registeredQualifiers.hasQualifiers(beanQualifiers,
requiredQualifiers.toArray(new Annotation[0]));
}
@Override
public boolean isMatchingEvent(Type specifiedType, Set<Annotation> specifiedQualifiers, Type observedEventType,
Set<Annotation> observedEventQualifiers) {
illegalNull(specifiedType, "specifiedType");
illegalNull(specifiedQualifiers, "specifiedQualifiers");
illegalNull(observedEventType, "observedEventType");
illegalNull(observedEventQualifiers, "observedEventQualifiers");
if (Types.containsTypeVariable(specifiedType)) {
throw new IllegalArgumentException("Event type contains a type variable: " + specifiedType);
}
ArcContainerImpl.instance().registeredQualifiers.verify(specifiedQualifiers);
ArcContainerImpl.instance().registeredQualifiers.verify(observedEventQualifiers);
Set<Annotation> eventQualifiers = new HashSet<>(specifiedQualifiers);
if (eventQualifiers.isEmpty()) {
eventQualifiers.add(Default.Literal.INSTANCE);
}
eventQualifiers.add(Any.Literal.INSTANCE);
Set<Type> eventTypes = new HierarchyDiscovery(specifiedType).getTypeClosure();
if (!EventTypeAssignabilityRules.instance().matches(observedEventType, eventTypes)) {
return false;
}
return ArcContainerImpl.instance().registeredQualifiers.isSubset(observedEventQualifiers, eventQualifiers);
}
private static void illegalNull(Object obj, String name) {View on GitHub (pinned to e1c734241f)
Solutions
- Pass a concrete Type (class, parameterized type with actual arguments) instead of the TypeVariable
- Capture the concrete type with a TypeLiteral subclass before the call
- Guard with Types.containsTypeVariable(specifiedType) and skip/throw a clearer error in your own code first
Example fix
// before
Type t = method.getGenericParameterTypes()[0]; // may be T
bm.isMatching(t, quals, observedType, obsQuals);
// after
Type t = new TypeLiteral<MyConcreteEvent>() {}.getType();
bm.isMatching(t, quals, observedType, obsQuals); Defensive patterns
Strategy: validation
Validate before calling
if (Types.containsTypeVariable(specifiedType)) {
throw new IllegalArgumentException("specifiedType must be concrete: " + specifiedType);
}
bm.isMatching(specifiedType, specifiedQualifiers, observedEventType, observedEventQualifiers); Type guard
boolean isConcreteEventType(Type t) {
return !Types.containsTypeVariable(t);
} Try / catch
try {
return isMatching(specifiedType, sq, ot, oq);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("type variable")) {
throw new IllegalStateException("Resolve specifiedType to a concrete Type first");
} else throw e;
} Prevention
- Never pass generic method/class type variables into event-matching APIs
- Capture concrete types with TypeLiteral subclasses in generic event wrappers
- Validate all Type arguments with Types.containsTypeVariable before CDI event calls
When it happens
Trigger: Calling event.isMatching(specifiedType, specifiedQualifiers, observedEventType, observedEventQualifiers) (or similar BeanManager event API) where specifiedType is a TypeVariable — typically a generic class's T or a wildcard-containing generic type obtained via reflection.
Common situations: Generic event-bus wrappers dispatching events for T; reflection frameworks passing getGenericType() results; meta-annotation/observer-introspection tooling written against generic classes.
Related errors
- Event injection point can never be raw type - please specify
- The runtime type of the event object contains a type variabl
- Event#select(Class<U>, Annotation...) cannot be used with ty
- Event#select(TypeLiteral, Annotation...) cannot be used with
- CDI event payload cannot contain unresolved type variable; f
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/ab8ad3abd3b722f8.
Report an issue: GitHub.