flowable/flowable-engine · error · ActivitiException
No matching parent execution for activity
Error message
No matching parent execution for activity ${errorHandlerId} found What it means
During error catch execution, the engine walks up the execution hierarchy to find the parent execution from which to leave toward the error handler activity. If no matching parent execution is found (matchingParentFound false or leavingExecution null), it throws ActivitiException.
Solutions
- Ensure the boundary error event is attached to the activity currently executing (or an enclosing scope) where the error is thrown
- Check concurrent execution structure: use exclusive/non-concurrent paths or verify parent execution links
- Redeploy a corrected process definition and restart affected instances
- Avoid throwing the error from a scope that has no path to the catching boundary event
Defensive patterns
Strategy: validation
Prevention
- Attach boundary error events to the activity actually throwing the error
- Keep execution paths non-concurrent across the throw/catch boundary or model scope-level catches
- Test error propagation scenarios (nested call activities, async scopes) in CI
When it happens
Trigger: The error handler activity (boundary/event subprocess handler) is not reachable from the failing execution's hierarchy — e.g. the boundary event belongs to an activity whose execution structure does not contain the current scope's parent chain.
Common situations: Concurrent/async scopes where the expected parent execution already ended; error thrown from an inner scope whose parent link is missing; process definition topology changed between versions; throwing error from outside the scope of the activity with the boundary 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
- Error Code must not be empty.
- Error Code must not be null.
- ${errorCode}
- No matching parent execution for error code " + errorId + "…
- Activity needed for multi instance cannot bv found
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/2d8e044d11de63e4.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/ErrorPropagation.java:174
} else {
currentActivity = currentActivity.getParentActivity();
leavingExecution = leavingExecution.getParent();
}
}
// Follow parents up until matching scope can't be found anymore (needed to support for multi-instance)
while (leavingExecution != null
&& leavingExecution.getParent() != null
&& leavingExecution.getParent().getActivity() != null
&& leavingExecution.getParent().getActivity().getId().equals(catchingScope.getId())) {
leavingExecution = leavingExecution.getParent();
}
}
if (matchingParentFound && leavingExecution != null) {
executeEventHandler(errorHandler, leavingExecution, errorCode);
} else {
throw new ActivitiException("No matching parent execution for activity " + errorHandlerId + " found");
}
}
}
private static void executeEventHandler(ActivityImpl borderEventActivity, ActivityExecution leavingExecution, String errorCode) {
if (Context.getProcessEngineConfiguration() != null && Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
Context.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(
ActivitiEventBuilder.createErrorEvent(FlowableEngineEventType.ACTIVITY_ERROR_RECEIVED, borderEventActivity.getId(), errorCode, leavingExecution.getId(), leavingExecution.getProcessInstanceId(),
leavingExecution.getProcessDefinitionId()),
EngineConfigurationConstants.KEY_PROCESS_ENGINE_CONFIG);
}
// The current activity of the execution will be changed in the next lines.
// So we must make sure the activity is ended correctly here
// The other executions (for example when doing something parallel in a subprocess, will
// be destroyed by the destroy scope operation (but this execution will be used to do it and
// will have list the original activity by then)View on GitHub (pinned to d6d39ce1c6)