flowable/flowable-engine · error · FlowableException
<e.getMessage()>
Error message
<e.getMessage()>
What it means
Catch-all in AppDeploymentCollectionResource.uploadDeployment: any exception that is not already a FlowableException is rethrown as a FlowableException whose message is the original exception's message (e.getMessage()). The meaningful detail is usually in the cause and server stack trace, since e.getMessage() can be terse or even null (e.g. from an NPE).
Source
Thrown at modules/flowable-app-engine-rest/src/main/java/org/flowable/app/rest/service/api/repository/AppDeploymentCollectionResource.java:231
deploymentBuilder.name(fileName);
if (tenantId != null) {
deploymentBuilder.tenantId(tenantId);
}
if (restApiInterceptor != null) {
restApiInterceptor.enhanceDeployment(deploymentBuilder);
}
AppDeployment deployment = deploymentBuilder.deploy();
return appRestResponseFactory.createAppDeploymentResponse(deployment);
} catch (Exception e) {
if (e instanceof FlowableException) {
throw (FlowableException) e;
}
throw new FlowableException(e.getMessage(), e);
}
}
public Map<String, String> splitQueryString(String queryString) {
if (StringUtils.isEmpty(queryString)) {
return Collections.emptyMap();
}
Map<String, String> queryMap = new HashMap<>();
for (String param : queryString.split("&")) {
queryMap.put(StringUtils.substringBefore(param, "="), decode(StringUtils.substringAfter(param, "=")));
}
return queryMap;
}
protected String decode(String string) {
if (string != null) {
return URLDecoder.decode(string, StandardCharsets.UTF_8);
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Inspect the server log stack trace for the wrapped cause (getCause()).
- Ensure the uploaded file is a valid .app or zip of valid app definitions.
- Verify DB connectivity and that deploymentName/tenant query params are present and non-empty.
- In client code, catch FlowableException and surface both message and cause.
Example fix
// before
throw new FlowableException(e.getMessage(), e); // message may be null
// after
String msg = e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName();
throw new FlowableException("Deployment failed: " + msg, e); Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight checks before deploying
if (StringUtils.isEmpty(deploymentName)) throw new IllegalArgumentException("deploymentName required");
if (!file.canRead()) throw new IllegalArgumentException("uploaded file unreadable"); Try / catch
try {
return uploadDeployment(request, tenantId);
} catch (FlowableException e) {
throw e; // server already classified it
} catch (Exception e) {
throw new FlowableException("Deployment failed: " + e, e); // include full exception; message may be null
} Prevention
- Always read the wrapped cause in server logs; the message alone can be null or empty.
- Validate uploaded content before deploy (valid .app/zip).
- Check DB connectivity — repository save failures surface here.
- Include the whole exception chain when reporting.
When it happens
Trigger: Any non-Flowable failure during deployment build/save: repository save errors, IO problems reading the uploaded file, NPEs from missing query params, resource conversion errors inside the deployment builder.
Common situations: DB connection failures during repositoryService.createDeployment().deploy(); invalid .app/zip content rejected by the underlying engine with a non-Flowable exception; NullPointerException whose message is null, producing a confusing empty message.
Related errors
- Could not find a resource with id '<resourceName>' in deploy
- Could not find an app deployment with id '<deploymentId>
- Error converting resource stream
- Could not find a deployment with id '<deploymentId>'.
- No resource name provided
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/5af30cdb1953640d.
Report an issue: GitHub.