quarkusio/quarkus · error · DeploymentException

Resource method '%s#%s' can only have a single body paramete

Error message

Resource method '%s#%s' can only have a single body parameter, but has at least 2. A body parameter is a method parameter without any annotations. Last discovered body parameter is '%s'.

What it means

EndpointIndexer.createResourceMethod assigns parameter roles for a JAX-RS resource method. A method may have at most one entity (body) parameter — a parameter without any JAX-RS annotations. When a second unannotated parameter is found, a DeploymentException is thrown stating the method can only have a single body parameter and naming the last discovered one.

Source

Thrown at independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java:635

                            .setType(ParameterType.SKIPPED);
                } else {
                    parameterResult = extractParameterInfo(currentClassInfo, actualEndpointInfo, currentMethodInfo,
                            existingConverters, additionalReaders,
                            anns, paramType, errorLocation, errorLocationParameters, false, hasRuntimeConverters,
                            pathParameters,
                            currentMethodInfo.parameterName(i),
                            consumes,
                            methodContext);
                }

                suspended |= parameterResult.isSuspended();
                sse |= parameterResult.isSse();
                String name = parameterResult.getName();
                String defaultValue = parameterResult.getDefaultValue();
                ParameterType type = parameterResult.getType();
                if (type == ParameterType.BODY) {
                    if (bodyParamType != null) {
                        throw new DeploymentException(String.format(
                                "Resource method '%s#%s' can only have a single body parameter, but has at least 2. A body parameter is a method parameter without any annotations. Last discovered body parameter is '%s'.",
                                currentMethodInfo.declaringClass().name(), currentMethodInfo,
                                currentMethodInfo.parameterName(i)));
                    }
                    bodyParamType = paramType;
                    if (GET.equals(httpMethod) || HEAD.equals(httpMethod) || OPTIONS.equals(httpMethod)) {
                        warnAboutMissUsedBodyParameter(httpMethod, currentMethodInfo);
                    }
                }
                String elementType = parameterResult.getElementType();
                boolean single = parameterResult.isSingle();
                if (defaultValue == null && paramType.kind() == Type.Kind.PRIMITIVE) {
                    defaultValue = "0";
                }
                methodParameters[i] = createMethodParameter(currentClassInfo, actualEndpointInfo, encoded, paramType,
                        parameterResult, name, defaultValue, type, elementType, single,
                        AsmUtil.getSignature(paramType, typeArgMapper), fileFormNames);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove or merge the extra unannotated parameters into a single body DTO
  2. Annotate the additional parameters with the appropriate JAX-RS annotation (@QueryParam, @HeaderParam, @PathParam, @Context, @BeanParam)
  3. Split the operation into two resource methods if two payloads are genuinely needed

Example fix

// before
@POST public void create(UserDto user, AddressDto address) { ... }
// after
@POST public void create(CreateRequest req /* contains user+address */) { ... }
Defensive patterns

Strategy: validation

Validate before calling

long bodyParams = Arrays.stream(method.getParameters())
    .filter(p -> Arrays.stream(p.getAnnotations())
        .noneMatch(a -> a.annotationType().getName().startsWith("jakarta.ws.rs.")))
    .count();
if (bodyParams > 1) throw new IllegalStateException("More than one body parameter on " + method);

Prevention

When it happens

Trigger: Declaring a resource method with two or more parameters lacking annotations such as @PathParam, @QueryParam, @HeaderParam, @Context, e.g. `void create(MyDto dto, OtherDto other)`, processed at build time.

Common situations: Forgetting @BeanParam/@QueryParam on additional parameters; assuming multiple DTOs can be merged from the body; refactor adding a second 'payload' argument.

Related errors


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