{"record":{"id":"b9b482e2399a3cdd","repo":"flowable/flowable-engine","slug":"multipart-request-is-required-b9b482","errorCode":null,"errorMessage":"Multipart request is required","messagePattern":"Multipart request is required","errorType":"http","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/repository/DeploymentCollectionResource.java","lineNumber":169,"sourceCode":"                    + \"An additional parameter (form-field) can be passed in the request body with name tenantId. The value of this field will be used as the id of the tenant this deployment is done in.\",\n            code = 201)\n    @ApiResponses(value = {\n            @ApiResponse(code = 201, message = \"Indicates the deployment was created.\"),\n            @ApiResponse(code = 400, message = \"Indicates there was no content present in the request body or the content mime-type is not supported for deployment. The status-description contains additional information.\")\n    })\n\n    @ApiImplicitParams({\n            @ApiImplicitParam(name = \"file\", dataType = \"file\", paramType = \"form\", required = true)\n    })\n    @PostMapping(value = \"/cmmn-repository/deployments\", produces = \"application/json\", consumes = \"multipart/form-data\")\n    @ResponseStatus(HttpStatus.CREATED)\n    public CmmnDeploymentResponse uploadDeployment(@ApiParam(name = \"deploymentKey\") @RequestParam(value = \"deploymentKey\", required = false) String deploymentKey,\n            @ApiParam(name = \"deploymentName\") @RequestParam(value = \"deploymentName\", required = false) String deploymentName,\n            @ApiParam(name = \"tenantId\") @RequestParam(value = \"tenantId\", required = false) String tenantId,\n            HttpServletRequest request) {\n\n        if (!(request instanceof MultipartHttpServletRequest)) {\n            throw new FlowableIllegalArgumentException(\"Multipart request is required\");\n        }\n        \n        if (restApiInterceptor != null) {\n            restApiInterceptor.executeNewDeploymentForTenantId(tenantId);\n        }\n\n        String queryString = request.getQueryString();\n        Map<String, String> decodedQueryStrings = splitQueryString(queryString);\n\n        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;\n\n        if (multipartRequest.getFileMap().size() == 0) {\n            throw new FlowableIllegalArgumentException(\"Multipart request with file content is required\");\n        }\n\n        MultipartFile file = multipartRequest.getFileMap().values().iterator().next();\n\n        try {","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/repository/DeploymentCollectionResource.java#L151-L187","documentation":"The CMMN REST deployment upload endpoint only accepts multipart/form-data requests because the deployment artifact (a .cmmn/.bar/.zip file) must be transmitted as a file part. The controller checks `request instanceof MultipartHttpServletRequest` and throws FlowableIllegalArgumentException when a plain (non-multipart) request is received.","triggerScenarios":"POST to /cmmn-query/repository/deployments (DeploymentCollectionResource.uploadDeployment) with Content-Type other than multipart/form-data, e.g. application/x-www-form-urlencoded or application/json, or a multipart request that failed to be parsed so Spring did not wrap it as MultipartHttpServletRequest.","commonSituations":"Clients using curl without -F, HTTP clients posting JSON bodies, a missing MultipartResolver/failed multipart parsing configuration, or proxies/gateways that strip or rewrite the Content-Type header.","solutions":["Send the request as multipart/form-data with the deployment file as a file part, e.g. `curl -F \"file=@myCase.cmmn.xml\" .../repository/deployments`.","Ensure the client sets Content-Type: multipart/form-data (let the HTTP library generate the boundary rather than setting it manually).","On the server, verify a MultipartResolver (e.g. StandardServletMultipartResolver) is configured and the servlet supports multipart (enable multipart in web.xml or via MultipartConfigElement).","Check intermediate proxies/API gateways preserve the multipart Content-Type and body."],"exampleFix":"// before\ncurl -X POST -H 'Content-Type: application/json' -d '{}' http://host/flowable-rest/cmmn-query/repository/deployments\n\n// after\ncurl -X POST -F 'file=@case.cmmn.xml' http://host/flowable-rest/cmmn-query/repository/deployments","handlingStrategy":"validation","validationCode":"if (!contentType || !contentType.startsWith('multipart/form-data')) {\n  throw new Error('Deployment upload requires multipart/form-data');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use the HTTP client's file-upload helper (curl -F, requests files=, FormData).","Never set the multipart boundary manually; let the library generate Content-Type.","Confirm the server has multipart parsing enabled before deploying via REST in a new environment."],"tags":["rest-api","multipart","http-client","flowable"],"backgroundTag":"invalid-argument-value","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}