{"record":{"id":"b6fd4f7507172885","repo":"quarkusio/quarkus","slug":"when-using-multi-as-body-parameter-only-multi-io-v","errorCode":null,"errorMessage":"When using Multi as body parameter only Multi<io.vertx.core.buffer.Buffer> is supported","messagePattern":"When using Multi as body parameter only Multi<io\\.vertx\\.core\\.buffer\\.Buffer> is supported","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/resteasy-reactive/rest-client-jaxrs/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java","lineNumber":1176,"sourceCode":"                                    methodCreator.getMethodParam(paramIdx), methodTarget, index,\n                                    restClientInterface.getClassName(),\n                                    methodCreator.getThis(),\n                                    handleBeanParamMethod.getThis(),\n                                    formParams, beanParamDescriptorsField, multipart,\n                                    beanParam.type);\n\n                            handleBeanParamMethod.returnValue(invocationBuilderRef);\n                            invocationBuilderEnrichers.put(handleBeanParamDescriptor, methodCreator.getMethodParam(paramIdx));\n                        } else if (param.parameterType == ParameterType.PATH) {\n                            // methodTarget = methodTarget.resolveTemplate(paramname, paramvalue);\n                            addPathParam(methodCreator, methodTarget, param.name, methodCreator.getMethodParam(paramIdx),\n                                    param.type, methodCreator.getThis(),\n                                    getGenericTypeFromArray(methodCreator, methodGenericParametersField, paramIdx),\n                                    getAnnotationsFromArray(methodCreator, methodParamAnnotationsField, paramIdx));\n                        } else if (param.parameterType == ParameterType.BODY) {\n                            if (param.declaredType.equals(Multi.class.getName())) {\n                                if (!param.signature.equals(MULTI_BUFFER_SIGNATURE)) {\n                                    throw new IllegalArgumentException(\n                                            \"When using Multi as body parameter only Multi<io.vertx.core.buffer.Buffer> is supported\");\n                                }\n                            }\n\n                            // just store the index of parameter used to create the body, we'll use it later\n                            bodyParameterIdx = paramIdx;\n                        } else if (param.parameterType == ParameterType.HEADER) {\n                            Type paramType = jandexMethod.parameterType(paramIdx);\n                            Type effectiveParamType = paramType;\n                            boolean isOptional = isOptional(paramType, index);\n                            if (isOptional) {\n                                effectiveParamType = Type.create(Object.class);\n                                if (paramType.kind() == PARAMETERIZED_TYPE) {\n                                    Type objectType = paramType.asParameterizedType().arguments().get(0);\n                                    if ((objectType.kind() == CLASS) || (objectType.kind() == PARAMETERIZED_TYPE)) {\n                                        effectiveParamType = objectType;\n                                    }\n                                }","sourceCodeStart":1158,"sourceCodeEnd":1194,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/resteasy-reactive/rest-client-jaxrs/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java#L1158-L1194","documentation":"When a REST client method body parameter is a Multi (reactive stream), the generator supports only Multi<io.vertx.core.buffer.Buffer> because it streams raw bytes. A Multi of any other element type (e.g. Multi<String>, Multi<byte[]>) cannot be wired as the request body and triggers an IllegalArgumentException at build time.","triggerScenarios":"Declaring a REST client POST/PUT method with a body parameter of type Multi<X> where X is not io.vertx.core.buffer.Buffer, e.g. Multi<String> or Multi<byte[]>.","commonSituations":"Trying to stream lines from a file or Kafka as Multi<String>; assuming automatic element encoding; migrating from a Publisher<byte[]> API.","solutions":["Change the parameter to Multi<io.vertx.core.buffer.Buffer> and encode elements yourself (e.g. Buffer.buffer(str))","Use Uni<String>/String for small bodies, or Multi<Buffer> after mapping: multi.map(Buffer::buffer)","If sending JSON lines, wrap into Buffer before passing"],"exampleFix":"// before\nResponse post(Multi<String> body);\n// after\nResponse post(Multi<io.vertx.core.buffer.Buffer> body); // map: multi.map(Buffer::buffer)","handlingStrategy":"validation","validationCode":"static void assertMultiBuffer(Class<?> raw, Type generic) { if (raw == Multi.class) { var arg = ((ParameterizedType) generic).getActualTypeArguments()[0]; if (arg != io.vertx.core.buffer.Buffer.class) throw new IllegalStateException(\"Multi body must be Multi<Buffer>\"); } }","typeGuard":"boolean isMultiBuffer(java.lang.reflect.Parameter p) { return !Multi.class.equals(p.getType()) || p.getParameterizedType() instanceof ParameterizedType pt && pt.getActualTypeArguments()[0] == io.vertx.core.buffer.Buffer.class; }","tryCatchPattern":"try { client.post(multi); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"Multi<io.vertx.core.buffer.Buffer>\")) { log.error(\"Map elements to Buffer before sending\"); } throw e; }","preventionTips":["Always use Multi<io.vertx.core.buffer.Buffer> for streamed bodies","Map elements: multi.map(Buffer::buffer) before passing","Use Uni/String for non-streamed payloads","Check the signature of Multi parameters against MULTI_BUFFER"],"tags":["quarkus","rest-client","reactive","multi","unsupported-type"],"backgroundTag":"unsupported-reactive-body-type","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}