{"record":{"id":"31984c15b474d9a3","repo":"quarkusio/quarkus","slug":"multipart-form-upload-expects-an-entity-of-type-mu","errorCode":null,"errorMessage":"Multipart form upload expects an entity of type MultipartForm or List<EntityPart>, got: \" + entityObj","messagePattern":"Multipart form upload expects an entity of type MultipartForm or List<EntityPart>, got: \" \\+ entityObj","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/handlers/ClientSendRequestHandler.java","lineNumber":605,"sourceCode":"    }\n\n    @SuppressWarnings(\"unchecked\")\n    private QuarkusMultipartFormUpload setMultipartHeadersAndPrepareBody(HttpClientRequest httpClientRequest,\n            RestClientRequestContext state) throws Exception {\n        QuarkusMultipartForm multipartForm;\n        Object entityObj = state.getEntity().getEntity();\n        boolean entityPartList = false;\n        if (entityObj instanceof GenericEntity<?> ge) {\n            entityPartList = EntityPartImpl.isEntityPartList(ge.getType());\n            entityObj = ge.getEntity();\n        }\n        if (entityObj instanceof QuarkusMultipartForm) {\n            multipartForm = (QuarkusMultipartForm) entityObj;\n        } else if (entityObj instanceof List<?> list\n                && (entityPartList || (!list.isEmpty() && list.get(0) instanceof EntityPart))) {\n            multipartForm = entityPartsToMultipartForm((List<EntityPart>) list);\n        } else {\n            throw new IllegalArgumentException(\n                    \"Multipart form upload expects an entity of type MultipartForm or List<EntityPart>, got: \" + entityObj);\n        }\n\n        MultivaluedMap<String, String> headerMap = state.getRequestHeadersAsMap();\n        updateRequestHeadersFromConfig(state, headerMap);\n        multipartForm.preparePojos(state);\n\n        Object property = state.getConfiguration().getProperty(QuarkusRestClientProperties.MULTIPART_ENCODER_MODE);\n        PausableHttpPostRequestEncoder.EncoderMode mode = PausableHttpPostRequestEncoder.EncoderMode.RFC1738;\n        if (property != null) {\n            mode = (PausableHttpPostRequestEncoder.EncoderMode) property;\n        }\n        QuarkusMultipartFormUpload multipartFormUpload = new QuarkusMultipartFormUpload(Vertx.currentContext(), multipartForm,\n                true, maxChunkSize, mode);\n        httpClientRequest.setChunked(multipartFormUpload.isChunked());\n        setEntityRelatedHeaders(headerMap, state.getEntity());\n\n        // multipart has its own headers:","sourceCodeStart":587,"sourceCodeEnd":623,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/handlers/ClientSendRequestHandler.java#L587-L623","documentation":"Before sending a multipart request, setMultipartHeadersAndPrepareBody expects the request entity to be either a QuarkusMultipartForm/MultipartForm or a List<EntityPart>. Any other entity object cannot be converted into a multipart body, so the handler throws IllegalArgumentException including the entity's actual value.","triggerScenarios":"Calling a client method declared with multipart form output but passing a mismatched entity: a raw POJO, a Map, a non-EntityPart List, or setting the entity manually via Invocation/REST-assured-style builders instead of using @MultipartForm-typed parameters or MultipartForm.","commonSituations":"Manually building requests with a POJO body while the endpoint expects multipart/form-data; generic client code reusing a JSON-entity call path for a multipart endpoint; List<T> where T is not EntityPart and the list is non-empty with entityPartList flag unset.","solutions":["Pass a MultipartForm (e.g. MultipartForm.create().binaryFileUpload(...)) as the request entity.","Or pass a List<EntityPart> built with EntityPart builder APIs.","For proxied clients, declare the parameter with @MultipartForm so the client constructs the correct body type.","Remove manual entity assignment that overrides the multipart body for multipart endpoints."],"exampleFix":"// before\nclient.post(Map.of(\"file\", data), FormData.class);\n// after\nMultipartForm form = MultipartForm.create()\n    .binaryFileUpload(\"file\", \"data.bin\", path, \"application/octet-stream\");\nclient.post(form, Response.class);","handlingStrategy":"type-guard","validationCode":"if (!(entity instanceof MultipartForm) && !(entity instanceof List<?> l && (l.isEmpty() || l.get(0) instanceof EntityPart))) {\n  throw new IllegalArgumentException(\"Multipart entity must be MultipartForm or List<EntityPart>\");\n}","typeGuard":"static boolean isValidMultipartEntity(Object e) {\n  return e instanceof MultipartForm\n      || (e instanceof List<?> l && !l.isEmpty() && l.stream().allMatch(EntityPart.class::isInstance));\n}","tryCatchPattern":null,"preventionTips":["Always send MultipartForm or List<EntityPart> for multipart endpoints","Use @MultipartForm parameters in proxied clients","Don't overwrite the entity on multipart request builders"],"tags":["rest-client","multipart","request-body","validation"],"backgroundTag":"invalid-request-entity-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"}