flowable/flowable-engine · error · FlowableException

${e.getMessage()}

Error message

${e.getMessage()}

What it means

uploadDeployment wraps the whole deployment operation in a try/catch: FlowableException subclasses are rethrown as-is, but any other Exception (IO errors, NPEs, runtime failures) is converted into a generic FlowableException whose message is the underlying exception's message. The reported message is therefore whatever the cause produced.

Solutions

  1. Read the 'cause' of the thrown FlowableException to find the real root error.
  2. Enable debug logging around the deployment call to capture the original stack trace.
  3. Fix the underlying cause (IO, DB, or null parameter) surfaced by the wrapped message.
  4. Wrap your client call in try/catch for FlowableException and log getCause().

Example fix

// before
throw new RuntimeException(e.getMessage());
// after (library behavior): inspect cause
catch (FlowableException e) {
    logger.error("deployment failed: {}", e.getCause(), e);
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try {
    uploadDeployment(file, params);
} catch (FlowableException e) {
    Throwable cause = e.getCause();
    logger.error("Deployment failed: {} (cause: {})", e.getMessage(), cause, e);
}

Prevention

When it happens

Trigger: Any unexpected exception during uploadDeployment: reading the uploaded InputStream fails, the underlying deployment service throws a non-Flowable exception, or query-string parsing hits an unexpected error.

Common situations: Corrupted upload streams, missing deployment parameters causing NPEs, database/IO failures during deployment persistence, catching a wrapped exception in tests without inspecting the cause.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/17feab6646e9919f. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-event-registry-rest/src/main/java/org/flowable/eventregistry/rest/service/api/repository/DeploymentCollectionResource.java:235

            }

            if (tenantId != null) {
                deploymentBuilder.tenantId(tenantId);
            }

            if (restApiInterceptor != null) {
                restApiInterceptor.enhanceDeployment(deploymentBuilder);
            }

            EventDeployment deployment = deploymentBuilder.deploy();

            return restResponseFactory.createDeploymentResponse(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)