flowable/flowable-engine · error · BpmnError
${errorCode}
${errorCode}
Error message
No catching boundary event found for error with errorCode '${errorCode}', neither in same process nor in parent process What it means
Raised as a BpmnError when an error is propagated (ErrorPropagation.propagateError) but neither the current process instance's activities nor any parent (call-activity) process contains a catching error boundary event / error event handler for the given errorCode. The error has nowhere to go, so the engine aborts.
Solutions
- Add an error boundary event (or error start event in an event subprocess) that catches the thrown errorCode on the appropriate activity
- Fix errorCode/errorRef mismatches (names are matched exactly) between thrower and catcher
- Ensure the parent process's call activity has a boundary error event when errors should cross the call boundary
- Declare a shared <error> element in the process definitions and reference it consistently
Example fix
// before <serviceTask id="t" flowable:class="X"/> <!-- no error catch --> // after <boundaryEvent id="catchErr" attachedToRef="t"> <errorEventDefinition errorRef="myError"/> </boundaryEvent>
Defensive patterns
Strategy: validation
Validate before calling
// before deploy: assert every thrown errorCode has a catcher
Set<String> thrown = setOf("myError");
Set<String> caught = collectErrorRefs(bpmnModel); // errorRefs on boundary/error-start events
if (!caught.containsAll(thrown)) throw new IllegalStateException("uncatched error codes: " + thrown);
if (!caught.containsAll(thrown)) throw new IllegalStateException("uncatched error codes: " + thrown); Try / catch
try {
runtimeService.trigger(executionId);
} catch (org.activiti.engine.delegate.BpmnError e) {
logger.error("Unhandled BPMN error: {}", e.getErrorCode());
throw e;
} Prevention
- Model a catching boundary/error-start event for every error code thrown
- Share <error> declarations between thrower and catcher definitions
- Add BPMN model validation to your build pipeline
When it happens
Trigger: An error end event or ErrorThrowingEventListener throws errorCode X while no boundary error event, error event subprocess, or parent-process handler catches X anywhere up the execution hierarchy.
Common situations: Typo or case mismatch between the thrown errorCode and the boundaryEvent's errorRef; boundary event attached to the wrong activity; missing error boundary on the call activity in the parent process; error event subprocess absent.
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
- Cannot start process instance. Process definition
- Cannot start process instance. Process model (id = " +…
- Cannot start process instance. Process model
- Error Code must not be empty.
- Error Code must not be null.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/1ba1a6e8f788ec46.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/ErrorPropagation.java:82
while (execution != null) {
String eventHandlerId = findLocalErrorEventHandler(execution, errorCode);
if (eventHandlerId != null) {
executeCatch(eventHandlerId, execution, errorCode);
break;
}
if (execution.isProcessInstanceType()) {
// dispatch process completed event
if (Context.getProcessEngineConfiguration() != null && Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createEntityEvent(FlowableEngineEventType.PROCESS_COMPLETED_WITH_ERROR_END_EVENT, execution),
EngineConfigurationConstants.KEY_PROCESS_ENGINE_CONFIG);
}
}
execution = getSuperExecution(execution);
}
if (execution == null) {
throw new BpmnError(errorCode, "No catching boundary event found for error with errorCode '"
+ errorCode + "', neither in same process nor in parent process");
}
}
private static String findLocalErrorEventHandler(ActivityExecution execution, String errorCode) {
PvmScope scope = execution.getActivity();
while (scope != null) {
@SuppressWarnings("unchecked")
List<ErrorEventDefinition> definitions = (List<ErrorEventDefinition>) scope.getProperty(BpmnParse.PROPERTYNAME_ERROR_EVENT_DEFINITIONS);
if (definitions != null) {
// definitions are sorted by precedence, ie. event subprocesses first.
for (ErrorEventDefinition errorEventDefinition : definitions) {
if (errorEventDefinition.catches(errorCode)) {
return scope.findActivity(errorEventDefinition.getHandlerActivityId()).getId();
}
}
}View on GitHub (pinned to d6d39ce1c6)