flowable/flowable-engine · error · FlowableIllegalArgumentException
File must be of type .app
Error message
File must be of type .app
What it means
Thrown by AppDeploymentCollectionResource.uploadDeployment when the uploaded file's name does not have an accepted extension: only '.app' files (single app definitions) or '.zip' files (handled in the if-branch via ZipInputStream) are accepted. Anything else hits the else branch and is rejected with FlowableIllegalArgumentException.
Source
Thrown at modules/flowable-app-engine-rest/src/main/java/org/flowable/app/rest/service/api/repository/AppDeploymentCollectionResource.java:190
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();
ZipInputStream zipInputStream = new ZipInputStream(fileInputStream)) {
deploymentBuilder.addZipInputStream(zipInputStream);
}
} else {
throw new FlowableIllegalArgumentException("File must be of type .app");
}
if (!decodedQueryStrings.containsKey("deploymentName") || StringUtils.isEmpty(decodedQueryStrings.get("deploymentName"))) {
String fileNameWithoutExtension = fileName.split("\\.")[0];
if (StringUtils.isNotEmpty(fileNameWithoutExtension)) {
fileName = fileNameWithoutExtension;
}
deploymentBuilder.name(fileName);
} else {
deploymentBuilder.name(decodedQueryStrings.get("deploymentName"));
}
if (decodedQueryStrings.containsKey("deploymentKey") && StringUtils.isNotEmpty(decodedQueryStrings.get("deploymentKey"))) {
deploymentBuilder.key(decodedQueryStrings.get("deploymentKey"));
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Upload a file with a .app extension (single app definition) or a .zip containing app definitions.
- If you have a .bar or raw XML, package it appropriately first (.app or a zip).
- Fix the client's Content-Disposition filename so the extension survives the upload.
- Check extension case matches what the code expects (lowercase .app/.zip).
Example fix
// before curl -F 'file=@myapp.bar' .../app-repository/deployments // after cp myapp.bar myapp.app curl -F 'file=@myapp.app' .../app-repository/deployments
Defensive patterns
Strategy: validation
Validate before calling
// Validate the extension before upload
String name = file.getName().toLowerCase();
if (!name.endsWith(".app") && !name.endsWith(".zip")) {
throw new IllegalArgumentException("Only .app or .zip files are accepted: " + name);
} Try / catch
try {
restTemplate.postForEntity(uploadUrl, requestEntity, AppDeploymentResponse.class);
} catch (HttpClientErrorException.BadRequest e) {
if (e.getResponseBodyAsString().contains("must be of type .app")) {
throw new IllegalArgumentException("Rename artifact to .app or package it in a .zip");
}
} Prevention
- Standardize on .app (single definition) or .zip (bundle) artifacts.
- Do not rename .bar archives without repackaging.
- Preserve the filename/extension in Content-Disposition.
- Check extension case-sensitivity.
When it happens
Trigger: POST /app-repository/deployments with a file whose name has another extension (e.g. .bar, .bpmn20.xml, .xml, or no extension at all).
Common situations: Renaming files without extensions; uploading a process archive (.bar, a BPM-suite convention not accepted here); exporting app definitions without the .app suffix; uppercase extensions if the check is case-sensitive.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Multipart request with file content is required
- Multipart request is required
- No deployment id provided
- Variable '${restVariable.getName()}' has unsupported type: '
- Unsupported variable query operation: ${friendlyName}
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/90828c0d2650351e.
Report an issue: GitHub.