{"record":{"id":"b328709d067d87e2","repo":"quarkusio/quarkus","slug":"resource-method-s-s-can-only-have-a-single-bod","errorCode":null,"errorMessage":"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'.","messagePattern":"Resource method '(.+?)#(.+?)' 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 '(.+?)'\\.","errorType":"validation","errorClass":"DeploymentException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java","lineNumber":635,"sourceCode":"                            .setType(ParameterType.SKIPPED);\n                } else {\n                    parameterResult = extractParameterInfo(currentClassInfo, actualEndpointInfo, currentMethodInfo,\n                            existingConverters, additionalReaders,\n                            anns, paramType, errorLocation, errorLocationParameters, false, hasRuntimeConverters,\n                            pathParameters,\n                            currentMethodInfo.parameterName(i),\n                            consumes,\n                            methodContext);\n                }\n\n                suspended |= parameterResult.isSuspended();\n                sse |= parameterResult.isSse();\n                String name = parameterResult.getName();\n                String defaultValue = parameterResult.getDefaultValue();\n                ParameterType type = parameterResult.getType();\n                if (type == ParameterType.BODY) {\n                    if (bodyParamType != null) {\n                        throw new DeploymentException(String.format(\n                                \"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'.\",\n                                currentMethodInfo.declaringClass().name(), currentMethodInfo,\n                                currentMethodInfo.parameterName(i)));\n                    }\n                    bodyParamType = paramType;\n                    if (GET.equals(httpMethod) || HEAD.equals(httpMethod) || OPTIONS.equals(httpMethod)) {\n                        warnAboutMissUsedBodyParameter(httpMethod, currentMethodInfo);\n                    }\n                }\n                String elementType = parameterResult.getElementType();\n                boolean single = parameterResult.isSingle();\n                if (defaultValue == null && paramType.kind() == Type.Kind.PRIMITIVE) {\n                    defaultValue = \"0\";\n                }\n                methodParameters[i] = createMethodParameter(currentClassInfo, actualEndpointInfo, encoded, paramType,\n                        parameterResult, name, defaultValue, type, elementType, single,\n                        AsmUtil.getSignature(paramType, typeArgMapper), fileFormNames);\n","sourceCodeStart":617,"sourceCodeEnd":653,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/common/processor/src/main/java/org/jboss/resteasy/reactive/common/processor/EndpointIndexer.java#L617-L653","documentation":"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.","triggerScenarios":"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.","commonSituations":"Forgetting @BeanParam/@QueryParam on additional parameters; assuming multiple DTOs can be merged from the body; refactor adding a second 'payload' argument.","solutions":["Remove or merge the extra unannotated parameters into a single body DTO","Annotate the additional parameters with the appropriate JAX-RS annotation (@QueryParam, @HeaderParam, @PathParam, @Context, @BeanParam)","Split the operation into two resource methods if two payloads are genuinely needed"],"exampleFix":"// before\n@POST public void create(UserDto user, AddressDto address) { ... }\n// after\n@POST public void create(CreateRequest req /* contains user+address */) { ... }","handlingStrategy":"validation","validationCode":"long bodyParams = Arrays.stream(method.getParameters())\n    .filter(p -> Arrays.stream(p.getAnnotations())\n        .noneMatch(a -> a.annotationType().getName().startsWith(\"jakarta.ws.rs.\")))\n    .count();\nif (bodyParams > 1) throw new IllegalStateException(\"More than one body parameter on \" + method);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Annotate every non-body parameter with a JAX-RS annotation","Consolidate multiple payloads into one request DTO","Lint resource methods for unannotated parameters in CI"],"tags":["jaxrs","deployment","parameters","build-time"],"backgroundTag":"multiple-body-parameters","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}