{"record":{"id":"c1fd44672af8e87c","repo":"flowable/flowable-engine","slug":"multipart-request-with-file-content-is-required-c1fd44","errorCode":null,"errorMessage":"Multipart request with file content is required","messagePattern":"Multipart request with file content is required","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/repository/DeploymentCollectionResource.java","lineNumber":183,"sourceCode":"            @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 {\n            DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();\n            String fileName = file.getOriginalFilename();\n            if (StringUtils.isEmpty(fileName) || !(fileName.endsWith(\".bpmn20.xml\") || fileName.endsWith(\".bpmn\") || fileName.toLowerCase().endsWith(\".bar\") || fileName.toLowerCase().endsWith(\".zip\"))) {\n\n                fileName = file.getName();\n            }\n\n            if (fileName.endsWith(\".bpmn20.xml\") || fileName.endsWith(\".bpmn\")) {\n            \ttry (final InputStream fileInputStream = file.getInputStream()) {\n                    deploymentBuilder.addInputStream(fileName, fileInputStream);\n                }\n            \t\n            } else if (fileName.toLowerCase().endsWith(\".bar\") || fileName.toLowerCase().endsWith(\".zip\")) {","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/repository/DeploymentCollectionResource.java#L165-L201","documentation":"FlowableIllegalArgumentException thrown when the request is multipart (previous check passed) but multipartRequest.getFileMap() is empty — no file part was included. A deployment upload must contain at least one file (.bpmn20.xml/.bpmn/.bar/.zip) to deploy.","triggerScenarios":"POST /repository/deployments as multipart/form-data containing only string fields (deploymentName, tenantId, deploymentKey) and no file part, or the file field sent under a name the resolver doesn't recognize as a file.","commonSituations":"See trigger scenarios.","solutions":["Attach the deployment artifact as a file part, e.g. curl -F \"file=@orderProcess.bpmn20.xml\"","Ensure the file input is a real MultipartFile part, not a JSON/base64 string field","Check the client sends the part with a standard file content-type so it lands in the multipart file map","Verify the file exists and is non-empty before uploading"],"exampleFix":"// before\ncurl -F \"deploymentName=d1\" -F \"tenantId=t1\" http://.../repository/deployments   // no file part\n// after\ncurl -F \"deploymentName=d1\" -F \"file=@orderProcess.bpmn20.xml\" http://.../repository/deployments","handlingStrategy":"validation","validationCode":"if (!fileField || fileField.size === 0) throw new Error('Deployment upload requires at least one file part');","typeGuard":"function hasFilePart(form) {\n  return Array.from(form.entries()).some(([, v]) => v instanceof File && v.size > 0);\n}","tryCatchPattern":"try {\n    deploy(multipartForm)\n} catch (BadRequest e) {\n    if (e.message?.includes('Multipart request with file content is required')) {\n        throw new Error('Add a file part (e.g. -F \"file=@process.bpmn20.xml\") to the request');\n    }\n}","preventionTips":["Verify the file exists and is non-empty before each upload","Send BPMN/ZIP data as a file part, not as a base64 string form field","Use a standard part name ('file') recognized by common client templates"],"tags":["multipart","missing-file","validation","rest"],"backgroundTag":"empty-required-field","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"}