{"record":{"id":"7c5da4a18b3f03a0","repo":"quarkusio/quarkus","slug":"event-select-typeliteral-annotation-cannot-be","errorCode":null,"errorMessage":"Event#select(TypeLiteral, Annotation...) cannot be used with type variable parameter","messagePattern":"Event#select\\(TypeLiteral, Annotation\\.\\.\\.\\) cannot be used with type variable parameter","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/EventImpl.java","lineNumber":160,"sourceCode":"    }\n\n    @Override\n    public <U extends T> Event<U> select(Class<U> subtype, Annotation... qualifiers) {\n        if (Types.containsTypeVariable(subtype)) {\n            throw new IllegalArgumentException(\n                    \"Event#select(Class<U>, Annotation...) cannot be used with type variable parameter\");\n        }\n        ArcContainerImpl.instance().registeredQualifiers.verify(qualifiers);\n        Set<Annotation> mergerdQualifiers = new HashSet<>(this.qualifiers);\n        Collections.addAll(mergerdQualifiers, qualifiers);\n        return new EventImpl<U>(subtype, mergerdQualifiers, injectionPoint);\n    }\n\n    @Override\n    public <U extends T> Event<U> select(TypeLiteral<U> subtype, Annotation... qualifiers) {\n        ArcContainerImpl.instance().registeredQualifiers.verify(qualifiers);\n        if (Types.containsTypeVariable(subtype.getType())) {\n            throw new IllegalArgumentException(\n                    \"Event#select(TypeLiteral, Annotation...) cannot be used with type variable parameter\");\n        }\n        Set<Annotation> mergerdQualifiers = new HashSet<>(this.qualifiers);\n        Collections.addAll(mergerdQualifiers, qualifiers);\n        return new EventImpl<U>(subtype.getType(), mergerdQualifiers, injectionPoint);\n    }\n\n    private Notifier<? super T> createNotifier(Class<?> runtimeType) {\n        Type eventType = getEventType(runtimeType);\n        return createNotifier(runtimeType, eventType, qualifiers, ArcContainerImpl.unwrap(Arc.requireContainer()),\n                injectionPoint);\n    }\n\n    static <T> Notifier<T> createNotifier(Class<?> runtimeType, Type eventType, Set<Annotation> qualifiers,\n            ArcContainerImpl container, InjectionPoint injectionPoint) {\n        return createNotifier(runtimeType, eventType, qualifiers, container, !Arc.requireContainer().strictCompatibility(),\n                injectionPoint);\n    }","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/EventImpl.java#L142-L178","documentation":"ArC (Quarkus's CDI implementation) rejects Event#select(TypeLiteral, Annotation...) when the given TypeLiteral's type still contains an unresolved type variable (e.g. select(new TypeLiteral<List<T>>(){}) where T is open). The CDI specification forbids this because the container could not determine a concrete event type to match observers. It is thrown eagerly from select() to fail fast.","triggerScenarios":"Calling event.select(new TypeLiteral<...>(){...}) where the TypeLiteral's type parameter references an unbound type variable, typically inside a generic class or generic method where the class's type parameter leaks into the literal.","commonSituations":"Helper/utility methods that wrap Event<T> and forward select() with the class's own type variable; generic DAO or service base classes selecting subtypes of a generic event payload.","solutions":["Call select() only with a fully concrete TypeLiteral (replace T with a real type at the call site)","Move the select() call out of the generic context and into a non-generic method that knows the concrete type","Pass the resolved Class/Type as a method argument from a non-generic caller and build the TypeLiteral from it","Capture the concrete type with an anonymous subclass of TypeLiteral at a point where the type is known"],"exampleFix":"// before (T unresolved)\npublic <T> void fireSub(Event<T> event) {\n    event.select(new TypeLiteral<Wrapper<T>>() {});\n}\n// after (concrete type)\nevent.select(new TypeLiteral<Wrapper<String>>() {});","handlingStrategy":"validation","validationCode":"static <U> TypeLiteral<U> requireConcrete(TypeLiteral<U> literal) {\n    if (io.quarkus.arc.impl.Types.containsTypeVariable(literal.getType())) {\n        throw new IllegalArgumentException(\"TypeLiteral must be fully concrete: \" + literal.getType());\n    }\n    return literal;\n}\n// usage: event.select(requireConcrete(new TypeLiteral<List<String>>() {}));","typeGuard":"static boolean isConcrete(Type t) {\n    return !io.quarkus.arc.impl.Types.containsTypeVariable(t);\n}","tryCatchPattern":"try {\n    event.select(literal, qualifiers);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"type variable\")) {\n        throw new IllegalStateException(\"Use a concrete TypeLiteral; got generic type\", e);\n    }\n    throw e;\n}","preventionTips":["Never pass TypeLiterals built from open type variables inside generic classes/methods","Keep event.select() calls in non-generic code where concrete types are known","Add a unit test that selects every event type used in the app"],"tags":["cdi","generics","arc","events"],"backgroundTag":"unresolved-type-variable","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}