quarkusio/quarkus · error · IllegalArgumentException

The runtime type of the event object contains a type variabl

Error message

The runtime type of the event object contains a type variable: ${eventType}

What it means

BeanManagerImpl.resolveObserverMethods(T event, ...) computes the canonical runtime type of the event object and rejects it if that type still contains a type variable. The CDI spec forbids resolving observer methods for event types with unresolved type variables, because assignability would be ill-defined.

Source

Thrown at independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/BeanManagerImpl.java:139

    public Bean<?> getPassivationCapableBean(String id) {
        throw new UnsupportedOperationException();
    }

    @Override
    public <X> Bean<? extends X> resolve(Set<Bean<? extends X>> beans) {
        return ArcContainerImpl.resolve(beans);
    }

    @Override
    public void validate(InjectionPoint injectionPoint) {
        throw new UnsupportedOperationException();
    }

    @Override
    public <T> Set<ObserverMethod<? super T>> resolveObserverMethods(T event, Annotation... qualifiers) {
        Type eventType = Types.getCanonicalType(event.getClass());
        if (Types.containsTypeVariable(eventType)) {
            throw new IllegalArgumentException("The runtime type of the event object contains a type variable: " + eventType);
        }
        Set<Annotation> eventQualifiers = new HashSet<>(Arrays.asList(qualifiers));
        return new LinkedHashSet<>(ArcContainerImpl.instance().resolveObserverMethods(eventType, eventQualifiers));
    }

    @Override
    public List<Decorator<?>> resolveDecorators(Set<Type> types, Annotation... qualifiers) {
        return ArcContainerImpl.instance().resolveDecorators(types, qualifiers);
    }

    @Override
    public List<Interceptor<?>> resolveInterceptors(InterceptionType type, Annotation... interceptorBindings) {
        return ArcContainerImpl.instance().resolveInterceptors(Objects.requireNonNull(type), interceptorBindings);
    }

    @Override
    public boolean isScope(Class<? extends Annotation> annotationType) {
        return ArcContainerImpl.instance().isScope(annotationType);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Use a concrete, non-generic event class (create a named subclass, e.g. class StringResult extends Result<String> {})
  2. Pass a non-generic payload (wrap generics in a concrete type or use a raw concrete class)
  3. Guard with Types.containsTypeVariable(Types.getCanonicalType(event.getClass())) before the call

Example fix

// before
Result<String> event = new Result<>();
bm.resolveObserverMethods(event); // canonical type still has T

// after
class StringResult extends Result<String> {}
bm.resolveObserverMethods(new StringResult());
Defensive patterns

Strategy: validation

Validate before calling

Type canonical = Types.getCanonicalType(event.getClass());
if (Types.containsTypeVariable(canonical)) {
    throw new IllegalArgumentException("Event type must be concrete: " + canonical);
}
bm.resolveObserverMethods(event, qualifiers);

Type guard

boolean isConcreteEventType(Class<?> eventClass) {
    return !Types.containsTypeVariable(Types.getCanonicalType(eventClass));
}

Try / catch

try {
    return bm.resolveObserverMethods(event, quals);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("type variable")) {
        throw new IllegalStateException("Use a concrete event subclass: " + event.getClass());
    } else throw e;
}

Prevention

When it happens

Trigger: Calling resolveObserverMethods with an instance whose runtime class is generic (e.g. Result<String>.class erasure path) or instantiating a raw/parameterized generic class and passing it; Types.getCanonicalType resolving to a type containing TypeVariables.

Common situations: Firing/resolving events of generic DTO wrapper types; reflection-driven event dispatch in custom frameworks; subclassing a generic event base class and passing an instance whose canonical type keeps T.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/7dc3e88257274cb3. Report an issue: GitHub.