quarkusio/quarkus · error · DefinitionException
Producer field type is a parameterized type with a type vari
Error message
Producer field type is a parameterized type with a type variable, its scope must be @Dependent: ${producerField} What it means
A producer field whose type is a parameterized type containing a type variable (e.g. Foo<T>) can only be safely resolved for @Dependent scope. Normal scopes require a proxyable, fully-resolvable bean type, so any other scope triggers this DefinitionException.
Source
Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Beans.java:333
if (isAlternative) {
if (priority == null) {
priority = declaringBean.getPriority();
}
priority = initAlternativePriority(producerField, priority, stereotypes, beanDeployment);
// after all attempts, priority is still null
if (priority == null) {
LOGGER.debugf(
"Ignoring producer field %s - declared as an @Alternative but not selected by @Priority or quarkus.arc.selected-alternatives",
producerField);
return null;
}
}
if (scope != null // `null` is just like `@Dependent`
&& !BuiltinScope.DEPENDENT.is(scope)
&& producerField.type().kind() == Kind.PARAMETERIZED_TYPE
&& Types.containsTypeVariable(producerField.type())) {
throw new DefinitionException("Producer field type is a parameterized type with a type variable, "
+ "its scope must be @Dependent: " + producerField);
}
BeanInfo bean = new BeanInfo(producerField, beanDeployment, scope, typeClosure.types(), qualifiers,
Collections.emptyList(),
declaringBean, disposer, isAlternative, stereotypes, name, isDefaultBean, null, priority,
typeClosure.unrestrictedTypes(), null);
return bean;
}
private static AnnotationInstance normalizedNamedQualifier(String defaultedName, AnnotationInstance originalAnnotation) {
// Replace @Named("") with @Named("foo")
// This is not explicitly defined by the spec but better align with the RI behavior
return AnnotationInstance.create(DotNames.NAMED, originalAnnotation.target(),
Collections.singletonList(AnnotationValue.createStringValue("value", defaultedName)));
}
private static DefinitionException multipleScopesFound(String baseMessage, List<ScopeInfo> scopes) {View on GitHub (pinned to e1c734241f)
Solutions
- Change the producer field's scope to @Dependent
- Replace the type variable with a concrete type in the producer field declaration
- Move the production into a producer method that resolves the type variable from the declaring bean's own parameter
Example fix
// before @ApplicationScoped @Produces Foo<T> foo; // after @Dependent @Produces Foo<T> foo;
Defensive patterns
Strategy: validation
Validate before calling
// check a producer field before compiling
boolean genericParam = field.type().kind() == org.jboss.jandex.Type.Kind.PARAMETERIZED_TYPE
&& Types.containsTypeVariable(field.type());
if (genericParam && !field.hasAnnotation(DotNames.DEPENDENT)) {
// fix: annotate the field with @Dependent
} Try / catch
try {
quarkusBuild.start();
} catch (DefinitionException e) {
if (e.getMessage().contains("its scope must be @Dependent")) {
logger.errorf("Make the generic producer @Dependent: %s", e.getMessage());
}
throw e;
} Prevention
- Pair any parameterized type with a type variable producer with @Dependent
- Prefer producer methods over producer fields for generic types
- Keep scope annotations minimal on generic classes
When it happens
Trigger: Beans.createProducerField sees a producer field with a non-null scope that is not @Dependent, whose declared type kind is PARAMETERIZED_TYPE and Types.containsTypeVariable() is true.
Common situations: Annotating a generic producer field like `Foo<T> foo` with @ApplicationScoped; porting a generic class to CDI without realizing the producer field keeps the type variable; after upgrading Quarkus which enforces this rule more strictly.
Related errors
- Declaring class of a managed bean is generic, its scope must
- InterceptionProxy parameter must be a parameterized type: ${
- A synthetic bean ${bean} was defined with invalid scope anno
- Type of injected Bean<T> does not match the type of the bean
- Injected @Intercepted Bean<?> has to use unbound wildcard as
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/18a21374d6c488bf.
Report an issue: GitHub.