quarkusio/quarkus · error · RuntimeException
Parameter '${parameterName}' of method '${targetMethod.name(
Error message
Parameter '${parameterName}' of method '${targetMethod.name()} of class '${targetClass.name()}' is not allowed What it means
getTargetMethodParamsInfo maps each @ServerExceptionMapper method parameter to a bytecode handle for a supported injectable type (Throwable, the handled exception, UriInfo, HttpHeaders, Request, ResourceInfo, CurrentRequest, etc.). A parameter whose type is not in the supported set cannot be injected, so a RuntimeException naming the offending parameter is thrown at build time.
Source
Thrown at independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/exceptionmappers/ServerExceptionMapperGenerator.java:610
BranchResult ifNullBranch = mc.ifNull(runtimeResourceHandle);
ifNullBranch.trueBranch().assign(resourceInfo, ifNullBranch.trueBranch().readStaticField(FieldDescriptor
.of(SimpleResourceInfo.NullValues.class, "INSTANCE", SimpleResourceInfo.NullValues.class)));
ifNullBranch.falseBranch().assign(resourceInfo, ifNullBranch.falseBranch().invokeVirtualMethod(
ofMethod(RuntimeResource.class, "getLazyMethod", ResteasyReactiveResourceInfo.class),
runtimeResourceHandle));
targetMethodParamHandles[i] = resourceInfo;
} else if (SIMPLIFIED_RESOURCE_INFO.equals(paramDotName)) {
ResultHandle runtimeResourceHandle = runtimeResourceHandle(mc, contextHandle);
AssignableResultHandle resourceInfo = mc.createVariable(SimpleResourceInfo.class);
BranchResult ifNullBranch = mc.ifNull(runtimeResourceHandle);
ifNullBranch.trueBranch().assign(resourceInfo, ifNullBranch.trueBranch().readStaticField(FieldDescriptor
.of(SimpleResourceInfo.NullValues.class, "INSTANCE", SimpleResourceInfo.NullValues.class)));
ifNullBranch.falseBranch().assign(resourceInfo, ifNullBranch.falseBranch().invokeVirtualMethod(
ofMethod(RuntimeResource.class, "getSimplifiedResourceInfo", SimpleResourceInfo.class),
runtimeResourceHandle));
targetMethodParamHandles[i] = resourceInfo;
} else {
throw new RuntimeException("Parameter '" + parameterName + "' of method '" + targetMethod.name()
+ " of class '" + targetClass.name()
+ "' is not allowed");
}
}
return new TargetMethodParamsInfo(targetMethodParamHandles, parameterTypes);
}
private static ReturnType determineReturnType(MethodInfo targetMethod) {
if (targetMethod.returnType().name().equals(RESPONSE)) {
return ReturnType.RESPONSE;
} else if (targetMethod.returnType().name().equals(REST_RESPONSE)) {
return ReturnType.REST_RESPONSE;
} else if (targetMethod.returnType().kind() == Type.Kind.PARAMETERIZED_TYPE) {
ParameterizedType parameterizedType = targetMethod.returnType().asParameterizedType();
if (parameterizedType.name().equals(UNI) && (parameterizedType.arguments().size() == 1)) {
if (parameterizedType.arguments().get(0).name().equals(RESPONSE)) {
return ReturnType.UNI_RESPONSE;
}View on GitHub (pinned to e1c734241f)
Solutions
- Remove the unsupported parameter and inject the needed object into the mapper class instead (field @Inject or constructor injection)
- Convert the parameter to one of the supported types (e.g. UriInfo, HttpHeaders, Request, ResourceInfo)
- Fetch required data via the supported context objects inside the method body
Example fix
// before
@ServerExceptionMapper
public Response map(NotFoundException e, MyService service) {...}
// after
public class MyMapper {
@Inject MyService service;
@ServerExceptionMapper
public Response map(NotFoundException e) {...}
} Defensive patterns
Strategy: validation
Validate before calling
// Verify mapper parameters are all injectable types
Set<Class<?>> allowed = Set.of(Throwable.class, UriInfo.class, HttpHeaders.class,
Request.class, ResourceInfo.class, SecurityContext.class, Providers.class,
jakarta.ws.rs.core.Application.class, Configuration.class);
for (Method m : mapperMethods) {
for (Class<?> p : m.getParameterTypes())
if (!allowed.contains(p)) throw new IllegalStateException("Unsupported mapper param " + p + " in " + m);
} Type guard
boolean isInjectableMapperParam(Class<?> p) {
return Throwable.class.isAssignableFrom(p)
|| p == UriInfo.class || p == HttpHeaders.class || p == Request.class
|| p == ResourceInfo.class || p == SecurityContext.class || p == Configuration.class;
} Prevention
- Only use exception + supported @Context-style types as mapper parameters
- Inject CDI beans via class fields/constructor injection, not method parameters
- Consult the RESTEasy Reactive docs list of supported mapper parameters
- Keep mapper signatures minimal and fetch auxiliary data inside the method body
When it happens
Trigger: A @ServerExceptionMapper method declares a parameter that is not the handled exception/Throwable and not one of the supported context types (UriInfo, HttpHeaders, Request, ResourceInfo, SecurityContext, Providers, Application, Configuration, SimpleResourceInfo...), e.g. a custom service or CDI bean.
Common situations: Injecting a CDI bean or custom context object directly into the mapper method; passing the request body or a DTO; assuming mapper methods can take arbitrary @Context-like parameters.
Related errors
- ReturnType: '${returnType}' is not supported
- Multiple method parameters found that extend 'Throwable'. Wh
- When '@ServerExceptionMapper' is used without a value, then
- Parameter '${parameterName}' of method '${targetMethod.name(
- The combination of '@${annotationName}' and '@ServerRequestF
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/b0acb980542067d5.
Report an issue: GitHub.