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
- Expected behavior: attach a boundary error event with a matching errorCode to catch it in the process
- Verify the errorCode string matches exactly (case-sensitive) between the thrown BpmnError and the boundary event definition
- 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
- Keep errorCode strings in constants shared between delegates and BPMN boundary events
- Accept BpmnError propagation as the designed business-error channel in v5 bridges
- Add boundary error events to migrated process definitions
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
- ${message}
- Can't deploy a v5 deployment with no flowable 5…
- with id has a v5 tag and flowable 5 compatibility is not…
- Flowable 5 process definitions are not supported
- Flowable 5 process definitions are not supported
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)