flowable/flowable-engine · error · FlowableException
Could not complete parent process instance for call activity
Error message
Could not complete parent process instance for call activity with process instance execution
What it means
While deleting a process instance that was started by a call activity, Flowable notifies the parent execution via SubProcessActivityBehavior.completing()/completed(). If any exception escapes those calls (e.g. the parent instance was concurrently deleted, its execution is in an invalid state, or a delegate/listener threw), it is wrapped in this FlowableException so the caller knows the parent process instance could not be completed.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/persistence/entity/ExecutionEntityManagerImpl.java:473
throw new FlowableObjectNotFoundException("No process instance found for id '" + processInstanceId + "'", ProcessInstance.class);
}
deleteProcessInstanceCascade(processInstanceExecution, ProcessInstanceState.CANCELLED, deleteReason, cascade, directDeleteInDatabase);
// Special care needed for a process instance of a call activity: the parent process instance needs to be triggered for completion
// This can't be added to the deleteProcessInstanceCascade method, as this will also trigger all child and/or multi-instance
// process instances for child call activities, which shouldn't happen.
if (processInstanceExecution.getSuperExecutionId() != null) {
ExecutionEntity superExecution = processInstanceExecution.getSuperExecution();
if (superExecution != null
&& superExecution.getCurrentFlowElement() instanceof FlowNode flowNode
&& flowNode.getBehavior() instanceof SubProcessActivityBehavior subProcessActivityBehavior) {
try {
subProcessActivityBehavior.completing(superExecution, processInstanceExecution);
superExecution.setSubProcessInstance(null);
subProcessActivityBehavior.completed(superExecution);
} catch (Exception e) {
throw new FlowableException("Could not complete parent process instance for call activity with process instance execution "
+ processInstanceExecution, e);
}
}
}
if (engineConfiguration.getEndProcessInstanceInterceptor() != null) {
engineConfiguration.getEndProcessInstanceInterceptor().afterEndProcessInstance(processInstanceId, ProcessInstanceState.CANCELLED);
}
}
protected void deleteProcessInstanceCascade(ExecutionEntity execution, String state, String deleteReason, boolean deleteHistory, boolean directDeleteInDatabase) {
// fill default reason if none provided
if (deleteReason == null) {
deleteReason = DeleteReason.PROCESS_INSTANCE_DELETED;
}
getActivityInstanceEntityManager().deleteActivityInstancesByProcessInstanceId(execution.getId());
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Inspect the wrapped cause (e.getCause()) — the real fix depends on it (optimistic lock, missing parent, listener bug).
- Avoid concurrent operations on parent/child instances: cancel the root process instance instead of individual call-activity children so both levels are handled atomically.
- If parent data is missing (copied environments), repair ACT_RU_EXECUTION hierarchy rows or delete orphaned instances via cascade delete / SQL cleanup.
- Fix any custom listener/behavior that throws inside completing()/completed().
Example fix
// before: cancelling a child call-activity instance directly runtimeService.deleteProcessInstance(childInstanceId, reason); // after: cancel at the root so parent completion is managed runtimeService.deleteProcessInstance(rootProcessInstanceId, reason);
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure parent is alive before cancelling the child
long parent = runtimeService.createProcessInstanceQuery()
.processInstanceId(parentInstanceId).count();
if (parent == 0) {
// cancel root instead, or skip
return;
} Try / catch
try {
runtimeService.deleteProcessInstance(childInstanceId, reason);
} catch (FlowableException e) {
if (e.getMessage().startsWith("Could not complete parent process instance")
&& e.getCause() != null) {
log.warn("parent completion failed", e.getCause());
} else { throw e; }
} Prevention
- Cancel the root process instance rather than individual call-activity children.
- Never operate on parent and child instances from parallel threads.
- Always log/examine getCause() — this exception wraps the real failure.
- Keep custom SubProcessActivityBehavior/listener code exception-safe.
When it happens
Trigger: runtimeService.deleteProcessInstance on a child call-activity instance while the parent's execution is gone/corrupted or concurrently modified; a custom SubProcessActivityBehavior or execution/listener on the parent's call-activity throws; deleting child instances in parallel from multiple threads.
Common situations: Cleanup jobs cancelling subprocess instances while the parent flow concurrently ends; data copied between environments missing parent ACT_RU_EXECUTION rows; custom call-activity behaviors with bugs.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Error while completing sub process of execution ${processIns
- Cannot start a sub process instance. Process model ${process
- No start element found for process definition ${processDefin
- Cannot start process instance. Process definition ${processD
- Unrecognized calledElementType [${calledElementType}] in ${e
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/5c4e6b484d488d18.
Report an issue: GitHub.