{"record":{"id":"a07056a089920ce7","repo":"quarkusio/quarkus","slug":"formparam-and-restform-can-only-be-used-on-m","errorCode":null,"errorMessage":"'@FormParam' and '@RestForm' can only be used on methods annotated with '@Consumes(MediaType.MULTIPART_FORM_DATA)' '@Consumes(MediaType.APPLICATION_FORM_URLENCODED)'. Offending method is '%s#%s'","messagePattern":"'@FormParam' and '@RestForm' can only be used on methods annotated with '@Consumes\\(MediaType\\.MULTIPART_FORM_DATA\\)' '@Consumes\\(MediaType\\.APPLICATION_FORM_URLENCODED\\)'\\. Offending method 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":684,"sourceCode":"                        && !bodyParamType.name().equals(ResteasyReactiveDotNames.MULTI_VALUED_MAP)\n                        && !bodyParamType.name().equals(ResteasyReactiveDotNames.STRING)) {\n                    throw new DeploymentException(String.format(\n                            \"'@FormParam' and '@RestForm' cannot be used in a resource method that contains a body parameter. Offending method is \"\n                                    + \"'%s#%s'\",\n                            currentMethodInfo.declaringClass().name(), currentMethodInfo));\n                }\n                boolean validConsumes = false;\n                if (consumes != null && consumes.length > 0) {\n                    for (String c : consumes) {\n                        if (c.startsWith(MediaType.MULTIPART_FORM_DATA)\n                                || c.startsWith(MediaType.APPLICATION_FORM_URLENCODED)) {\n                            validConsumes = true;\n                            break;\n                        }\n                    }\n                    // TODO: does it make sense to default to MediaType.MULTIPART_FORM_DATA when no consumes is set?\n                    if (!validConsumes) {\n                        throw new DeploymentException(String.format(\n                                \"'@FormParam' and '@RestForm' can only be used on methods annotated with '@Consumes(MediaType.MULTIPART_FORM_DATA)' '@Consumes(MediaType.APPLICATION_FORM_URLENCODED)'. Offending method is \"\n                                        + \"'%s#%s'\",\n                                currentMethodInfo.declaringClass().name(), currentMethodInfo));\n                    }\n                }\n            }\n\n            Type methodContextReturnTypeOrReturnType = methodContext.containsKey(METHOD_CONTEXT_CUSTOM_RETURN_TYPE_KEY)\n                    ? (Type) methodContext.get(METHOD_CONTEXT_CUSTOM_RETURN_TYPE_KEY)\n                    : currentMethodInfo.returnType();\n            if (REST_RESPONSE.equals(methodContextReturnTypeOrReturnType.name())\n                    && (methodContextReturnTypeOrReturnType.kind() == Kind.CLASS)) {\n                log.warnf(\"Method '%s' of Resource class '%s' returns RestResponse but does not declare a generic type. \"\n                        + \"It is strongly advised to define the generic type otherwise the behavior could be unpredictable\",\n                        currentMethodInfo, currentMethodInfo.declaringClass().name());\n            }\n            Type nonAsyncReturnType = getNonAsyncReturnType(methodContextReturnTypeOrReturnType);\n            addWriterForType(additionalWriters, nonAsyncReturnType);","sourceCodeStart":666,"sourceCodeEnd":702,"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#L666-L702","documentation":"Methods using @FormParam/@RestForm must declare @Consumes of either multipart/form-data or application/x-www-form-urlencoded, because form parameters can only be extracted from those media types. EndpointIndexer validates the method's @Produces/@Consumes metadata during deployment and throws if no valid consumes value is present.","triggerScenarios":"A resource method has @FormParam/@RestForm parameters but its @Consumes annotation lists a media type other than MULTIPART_FORM_DATA or APPLICATION_FORM_URLENCODED (e.g. application/json), or omits @Consumes entirely while a class-level @Consumes application/json applies.","commonSituations":"Forgetting @Consumes when adding form params; a class-level @Consumes(MediaType.APPLICATION_JSON) overriding expectations; form params left over after changing a method from form submission to JSON body handling.","solutions":["Add or correct @Consumes on the method: @Consumes(MediaType.MULTIPART_FORM_DATA) for file/multipart uploads or @Consumes(MediaType.APPLICATION_FORM_URLENCODED) for plain form posts","Remove @FormParam/@RestForm parameters if the method really consumes JSON or another content type","Check for inherited/class-level @Consumes annotations that restrict the allowed media types"],"exampleFix":"// before\n@POST\npublic String submit(@RestForm String name) { ... }\n// after\n@POST\n@Consumes(MediaType.APPLICATION_FORM_URLENCODED)\npublic String submit(@RestForm String name) { ... }","handlingStrategy":"validation","validationCode":"Consumes consumes = MyResource.class.getMethod(\"submit\", String.class)\n    .getAnnotation(Consumes.class);\nboolean ok = consumes != null && java.util.Arrays.stream(consumes.value()).anyMatch(\n    mt -> mt.equals(MediaType.MULTIPART_FORM_DATA) || mt.equals(MediaType.APPLICATION_FORM_URLENCODED));\nif (!ok) throw new IllegalStateException(\"Form-param method must consume multipart/form-data or application/x-www-form-urlencoded\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pair @RestForm/@FormParam methods with an explicit method-level @Consumes","Remember class-level @Consumes applies when method-level is absent — audit it","Use a code-review checklist item: form param => form/multipart consumes","Run a quick quarkus:dev build locally before pushing; this error surfaces at deployment"],"tags":["quarkus","resteasy-reactive","consumes","form-params","deployment"],"backgroundTag":"unsupported-consumes-media-type","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"}