flowable/flowable-engine · error · FlowableException

No matching parent execution for error code " + errorId + "…

Error message

No matching parent execution for error code " + errorId + " found for " + delegateExecution

What it means

Thrown by ErrorPropagation.executeCatch as a FlowableException when an error being propagated (propagateError) cannot be matched to any parent execution's error boundary event, error start event, or event handler for the given error code. No catch construct exists anywhere in the parent execution hierarchy, so Flowable cannot deliver the error.

Solutions

  1. Add or fix an error boundary event / error event subprocess whose errorRef matches the thrown error code
  2. Ensure the boundary event is attached to the correct activity (one that encloses the throwing execution)
  3. Verify the error code string matches exactly (case, whitespace) between throw site and catch definition
  4. If the process should end on unmatched errors, catch the BpmnError earlier or add a fallback error event subprocess

Example fix

// before: no catch defined, delegate throws
throw new BpmnError("VALIDATION_FAILED");
// after: add to BPMN on the enclosing service task
<boundaryEvent id="catchValidation" attachedToRef="validateTask">
  <errorEventDefinition errorRef="VALIDATION_FAILED"/>
</boundaryEvent>
Defensive patterns

Strategy: validation

Validate before calling

// Before throwing, confirm a catch exists for the error code in the deployment
boolean hasCatch = model.getBpmnModel().getMainProcess().getFlowElementsStream()
    .anyMatch(fe -> fe instanceof BoundaryEvent
        && ((BoundaryEvent) fe).getEventDefinitions().stream()
            .anyMatch(ed -> ed instanceof ErrorEventDefinition
                && code.equals(((ErrorEventDefinition) ed).getErrorRef())));
if (!hasCatch) throw new IllegalStateException("No boundary event catches error code " + code);

Try / catch

try { runtimeService.startProcessInstanceByKey(key, vars); }
catch (FlowableException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("No matching parent execution for error code")) {
        log.error("Uncaught BPMN error: {}", e.getMessage());
    } else throw e;
}

Prevention

When it happens

Trigger: A BpmnError is thrown (BpmnError.throwException / delegateExecution) with an error code, but no error boundary event, error event subprocess, or error start event matching that code exists on any parent execution — the matching lookup returns null and executeCatch throws.

Common situations: Typo or mismatch between the thrown error code and the boundary event's errorRef; missing errorRef attribute on the boundary event; error thrown from a call activity or listener where the catching scope was expected to exist; error code changed in the delegate but not in the model.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/ErrorPropagation.java:264

                                                "ERROR_EVENT " + errorId, false, false, false);

                // Event
                ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
                FlowableEventDispatcher eventDispatcher = null;
                if (processEngineConfiguration != null) {
                    eventDispatcher = processEngineConfiguration.getEventDispatcher();
                }
                if (eventDispatcher != null && eventDispatcher.isEnabled()) {
                    processEngineConfiguration.getEventDispatcher()
                            .dispatchEvent(FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.PROCESS_COMPLETED_WITH_ERROR_END_EVENT, processInstanceEntity),
                                    processEngineConfiguration.getEngineCfgKey());
                }
            }

            executeEventHandler(matchingEvent, parentExecution, currentExecution, errorVariableContainer);

        } else {
            throw new FlowableException("No matching parent execution for error code " + errorId + " found for " + delegateExecution);
        }
    }

    protected static void executeEventHandler(Event event, ExecutionEntity parentExecution, ExecutionEntity currentExecution,
            BpmnErrorVariableContainer errorVariableContainer) {
        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
        FlowableEventDispatcher eventDispatcher = null;

        String errorId = errorVariableContainer.getErrorCode();
        String errorCode = errorId;
        BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(parentExecution.getProcessDefinitionId());
        if (bpmnModel != null) {
            String modelError = bpmnModel.getErrors().get(errorId);
            if (modelError != null) {
                errorCode = modelError;
                errorVariableContainer.setErrorCode(errorCode);
            }
        }

View on GitHub (pinned to d6d39ce1c6)