flowable/flowable-engine · warning · BpmnError

(errorCode=' ')

Error message

${message} (errorCode='${errorCode}')

What it means

In handleActivitiException, an Activiti 5 BpmnError crossing the compatibility boundary is rethrown as a Flowable BpmnError carrying the original errorCode and message. This is a faithful translation, not a malfunction — the v5 error propagation is mapped onto the v6 BpmnError type.

Solutions

  1. Expected behavior: attach a boundary error event with a matching errorCode to catch it in the process
  2. Verify the errorCode string matches exactly (case-sensitive) between the thrown BpmnError and the boundary event definition
  3. If it should not propagate, remove or guard the BpmnError throw in the v5 delegate

Example fix

// before
throw new org.activiti.engine.delegate.BpmnError("ERR_404");
// after (catch on boundary event <boundaryEvent errorRef="ERR_404">) or handle explicitly:
try { delegate.execute(execution); } catch (BpmnError e) { /* handle */ }
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the boundary error event exists for the errorCode before the process runs
assert processDefinitionContainsBoundaryError(processDefinitionId, "ERR_404");

Try / catch

try {
    handler.executeJob(job);
} catch (BpmnError e) {
    execution.getProcessInstance().signal("boundary-" + e.getErrorCode()); // or let engine route it
}

Prevention

When it happens

Trigger: Executing a v5-style service task/delegate through the compatibility handler that signals a BpmnError (throw new org.activiti.engine.delegate.BpmnError(code, msg) or an ActivitiException whose translation path reaches the BpmnError branch).

Common situations: Migrated Activiti 5 Java delegates/execution listeners signaling business errors that are expected to be caught by a v6 boundary error event.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable5-compatibility/src/main/java/org/flowable/compatibility/DefaultFlowable5CompatibilityHandler.java:1162

        activity5Job.setExecutionId(job.getExecutionId());
        activity5Job.setId(job.getId());
        activity5Job.setJobHandlerConfiguration(job.getJobHandlerConfiguration());
        activity5Job.setJobHandlerType(job.getJobHandlerType());
        activity5Job.setEndDate(job.getEndDate());
        activity5Job.setRepeat(job.getRepeat());
        activity5Job.setProcessDefinitionId(job.getProcessDefinitionId());
        activity5Job.setProcessInstanceId(job.getProcessInstanceId());
        activity5Job.setRetries(job.getRetries());
        activity5Job.setRevision(job.getRevision());
        activity5Job.setTenantId(job.getTenantId());
        activity5Job.setExceptionMessage(job.getExceptionMessage());
        return activity5Job;
    }

    protected void handleActivitiException(org.activiti.engine.ActivitiException e) {
        if (e instanceof org.activiti.engine.delegate.BpmnError) {
            org.activiti.engine.delegate.BpmnError activiti5BpmnError = (org.activiti.engine.delegate.BpmnError) e;
            throw new BpmnError(activiti5BpmnError.getErrorCode(), activiti5BpmnError.getMessage());

        } else if (e instanceof org.activiti.engine.ActivitiClassLoadingException) {
            throw new FlowableClassLoadingException(e.getMessage(), e.getCause());

        } else if (e instanceof org.activiti.engine.ActivitiObjectNotFoundException) {
            org.activiti.engine.ActivitiObjectNotFoundException activiti5ObjectNotFoundException = (org.activiti.engine.ActivitiObjectNotFoundException) e;
            throw new FlowableObjectNotFoundException(activiti5ObjectNotFoundException.getMessage(),
                    activiti5ObjectNotFoundException.getObjectClass(), activiti5ObjectNotFoundException.getCause());

        } else if (e instanceof org.activiti.engine.ActivitiOptimisticLockingException) {
            throw new FlowableOptimisticLockingException(e.getMessage());

        } else if (e instanceof org.activiti.engine.ActivitiIllegalArgumentException) {
            throw new FlowableIllegalArgumentException(e.getMessage(), e.getCause());

        } else {
            if (e.getCause() instanceof org.activiti.engine.delegate.BpmnError) {
                org.activiti.engine.delegate.BpmnError activiti5BpmnError = (org.activiti.engine.delegate.BpmnError) e.getCause();

View on GitHub (pinned to d6d39ce1c6)