flowable/flowable-engine · error · FlowableIllegalArgumentException
Multipart request with file content is required
Error message
Multipart request with file content is required
What it means
Thrown by AppDeploymentCollectionResource.uploadDeployment when the request is multipart but contains no file entries (multipartRequest.getFileMap().size() == 0). Flowable needs at least one file part to build the deployment. It signals a structurally valid multipart request with missing file content.
Source
Thrown at modules/flowable-app-engine-rest/src/main/java/org/flowable/app/rest/service/api/repository/AppDeploymentCollectionResource.java:165
@PostMapping(value = "/app-repository/deployments", produces = "application/json", consumes = "multipart/form-data")
@ResponseStatus(HttpStatus.CREATED)
public AppDeploymentResponse uploadDeployment(@ApiParam(name = "tenantId") @RequestParam(value = "tenantId", required = false) String tenantId, HttpServletRequest request) {
if (restApiInterceptor != null) {
restApiInterceptor.executeNewDeploymentForTenantId(tenantId);
}
if (!(request instanceof MultipartHttpServletRequest)) {
throw new FlowableIllegalArgumentException("Multipart request is required");
}
String queryString = request.getQueryString();
Map<String, String> decodedQueryStrings = splitQueryString(queryString);
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
if (multipartRequest.getFileMap().size() == 0) {
throw new FlowableIllegalArgumentException("Multipart request with file content is required");
}
MultipartFile file = multipartRequest.getFileMap().values().iterator().next();
try {
AppDeploymentBuilder deploymentBuilder = appRepositoryService.createDeployment();
String fileName = file.getOriginalFilename();
if (StringUtils.isEmpty(fileName) || !(fileName.endsWith(".app") || fileName.toLowerCase().endsWith(".bar") || fileName.toLowerCase().endsWith(".zip"))) {
fileName = file.getName();
}
if (fileName.endsWith(".app")) {
try (final InputStream fileInputStream = file.getInputStream()) {
deploymentBuilder.addInputStream(fileName, fileInputStream);
}
} else if (fileName.toLowerCase().endsWith(".bar") || fileName.toLowerCase().endsWith(".zip")) {
try (InputStream fileInputStream = file.getInputStream();View on GitHub (pinned to d6d39ce1c6)
Solutions
- Attach at least one file part, e.g. FormData.append('file', fileObject) in JS or curl -F 'file=@my.app'.
- Use a proper file input (<input type='file'>) so the part is a file, not a text field.
- Verify the part is non-empty and has a filename.
- Log multipartRequest.getFileMap() server-side to confirm which parts Spring sees.
Example fix
// before
const fd = new FormData(); fd.append('deploymentName', 'x'); // no file part
// after
const fd = new FormData();
fd.append('file', appFileInput.files[0]);
fd.append('deploymentName', 'x'); Defensive patterns
Strategy: validation
Validate before calling
// client-side: ensure a file part is appended
if (!fileInput.files || fileInput.files.length === 0) {
throw new Error('Select an .app or .zip file before uploading');
}
const fd = new FormData();
fd.append('file', fileInput.files[0]); Try / catch
try {
restTemplate.postForEntity(uploadUrl, requestEntity, String.class);
} catch (HttpClientErrorException.BadRequest e) {
if (e.getResponseBodyAsString().contains("file content is required")) {
// retry with an actual file part in the multipart body
}
} Prevention
- Always append a file object (not a string field) as the file part.
- Use <input type='file'> with a real File/Blob.
- Never send an empty file part.
- Test uploads with curl -F before wiring UI code.
When it happens
Trigger: POST /app-repository/deployments with multipart/form-data but only text/field parts, or an empty file part not registered in the file map.
Common situations: Client sends form fields (deploymentName etc.) but forgets the file input; wrong part name/type so Spring does not classify it as a file; browser form without enctype='multipart/form-data'; empty FormData append.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Multipart request is required
- File must be of type .app
- No file content was found in request body.
- Could not process multipart content
- Error getting binary variable
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/fbb1b6ec1f46ef01.
Report an issue: GitHub.