quarkusio/quarkus · error · DeploymentException

Resource classes that use field injection for REST parameter

Error message

Resource classes that use field injection for REST parameters can only be @RequestScoped. Offending class is ${classInfo.name()}

What it means

RESTEasy Reactive supports REST parameter field injection (e.g. @QueryParam on fields) only in @RequestScoped resource classes, because the injected values are per-request. When the endpoint indexer detects a class needing field injection whose effective scope is not @RequestScoped, deployment fails with this DeploymentException.

Source

Thrown at extensions/resteasy-reactive/rest/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/QuarkusServerEndpointIndexer.java:293

            return;
        }
        super.warnAboutMissUsedBodyParameter(httpMethod, methodInfo);
    }

    /**
     * At this point we know exactly which resources will require field injection and therefore are required to be
     * {@link RequestScoped}.
     * We can't change anything CDI related at this point (because it would create build cycles), so all we can do
     * is fail the build if the resource has not already been handled automatically (by the best effort approach performed
     * elsewhere)
     * or it's not manually set to be {@link RequestScoped}.
     */
    @Override
    protected void verifyClassThatRequiresFieldInjection(ClassInfo classInfo) {
        if (!alreadyHandledRequestScopedResources.contains(classInfo.name())) {
            BuiltinScope scope = BuiltinScope.from(classInfo);
            if (BuiltinScope.REQUEST != scope) {
                throw new DeploymentException(
                        "Resource classes that use field injection for REST parameters can only be @RequestScoped. Offending class is "
                                + classInfo.name());
            }
        }
    }

}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Annotate the resource class with @RequestScoped
  2. Convert field injection to method parameter injection (move @QueryParam/@PathParam onto the resource method) and keep any scope you need
  3. Use constructor injection with String-typed parameters instead of field injection
  4. Remove the non-request scope annotation if the class should be request-scoped by default

Example fix

// before
@ApplicationScoped
@Path("/greet")
public class GreetingResource {
    @QueryParam("name")
    String name;
}
// after
@RequestScoped
@Path("/greet")
public class GreetingResource {
    @QueryParam("name")
    String name;
}
Defensive patterns

Strategy: validation

Validate before calling

// before build: resource uses field injection of REST params?
boolean fieldInjection = Arrays.stream(resourceClass.getDeclaredFields())
        .anyMatch(f -> Arrays.stream(f.getAnnotations()).anyMatch(a ->
                a.annotationType().getName().startsWith("jakarta.ws.rs.")));
boolean requestScoped = resourceClass.isAnnotationPresent(jakarta.enterprise.context.RequestScoped.class);
if (fieldInjection && !requestScoped)
    throw new IllegalStateException(resourceClass + " uses REST field injection and must be @RequestScoped");

Prevention

When it happens

Trigger: A resource class declares JAX-RS parameter annotations on fields (@QueryParam/@PathParam/@HeaderParam on instance fields) and the class is annotated with (or resolves to) a scope other than @RequestScoped — e.g. @Singleton or @ApplicationScoped.

Common situations: Marking resources @ApplicationScoped or @Singleton for perceived performance benefits while also using field injection of request parameters; migrating from classic RESTEasy where such combinations were tolerated differently.

Related errors


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