flowable/flowable-engine · error · FlowableException
Call activity '" + executionActivityId + "' does not exist…
Error message
Call activity '" + executionActivityId + "' does not exist in the new model. It must be mapped explicitly for migration (or all its child activities)
What it means
Thrown during auto-mapping when a call activity with running (unmapped) child instances has no explicit mapping and its activity id does not exist in the target process model. Migration of call activities with unmapped children requires the call activity itself to exist unchanged in the new model, otherwise instance state would be lost. The developer must map it explicitly.
Solutions
- Add an explicit activity mapping for the call activity in the migration document: .addActivityMapping(oldId, newId)
- Map all running child activities of the call activity explicitly so auto-mapping is not needed
- Restore or keep the call activity id unchanged in the target model
- Migrate the child process instances separately or terminate them before migrating
Example fix
// before
runtimeService.createProcessInstanceMigrationBuilder()
.migrateToProcessDefinition(newDefId) // callActivity 'callTask1' removed in new model
.migrate(instanceId);
// after
runtimeService.createProcessInstanceMigrationBuilder()
.migrateToProcessDefinition(newDefId)
.addActivityMapping("callTask1", "callTask2") // explicit mapping
.migrate(instanceId); Defensive patterns
Strategy: validation
Validate before calling
ProcessDefinition newDef = repositoryService.getProcessDefinition(targetDefId);
BpmnModel newModel = repositoryService.getBpmnModel(newDef.getId());
if (newModel.getFlowElement("callTask1") == null && runningChildrenUnmapped) {
// add explicit mapping for callTask1 before migrating
} Try / catch
try {
migrationBuilder.migrate(instanceId);
} catch (FlowableException e) {
if (e.getMessage().contains("Call activity") && e.getMessage().contains("does not exist in the new model")) {
// rebuild document with explicit call activity mapping
}
} Prevention
- Always run validateMigrations before migrate()
- Keep call activity ids stable across versions
- Map call activities explicitly whenever their children are running
- Diff old and new BpmnModels in tests before deploying breaking versions
When it happens
Trigger: Migrating a process instance whose current execution tree contains a call activity with running child process instances, no activity mapping covers the call activity (or all its children), and the target model has no flow element with that id.
Common situations: The new model renamed or removed the call activity; a process refactor deleted the sub-process invocation; the migration document omitted mappings for the call activity's children.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Call activity '" + executionActivityId + "' has a different…
- Call activity '" + executionActivityId + "' is not a Call…
- Call activity '" + executionActivityId + "' loop…
- Migration Activity mapping missing for activity definition…
- Migration Activity mapping missing for activity definition…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/f1d1e1dde7a6f88e.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationManagerImpl.java:694
if (subProcessActivityMappingsByCallActivityIdAndFromActivityId.containsKey(executionActivityId)) {
Set<String> mappedSubProcessActivityIds = subProcessActivityMappingsByCallActivityIdAndFromActivityId.get(executionActivityId).keySet();
List<ExecutionEntity> callActivityExecutions = filteredExecutionsByActivityId.get(executionActivityId).stream().filter(ExecutionEntity::isActive).collect(Collectors.toList());
for (ExecutionEntity callActivityExecution : callActivityExecutions) { //parallel MultiInstance call activities
List<ExecutionEntity> subProcessChildExecutions = executionEntityManager.findChildExecutionsByProcessInstanceId(callActivityExecution.getSubProcessInstance().getId());
Set<String> childSubProcessExecutionActivityIds = subProcessChildExecutions.stream().map(Execution::getActivityId).collect(Collectors.toSet());
childSubProcessExecutionActivityIds.removeAll(mappedSubProcessActivityIds);
if (!childSubProcessExecutionActivityIds.isEmpty()) {
runningChildrenNotFullyMapped = true;
break;
}
}
}
if (!subProcessActivityMappingsByCallActivityIdAndFromActivityId.containsKey(executionActivityId) || runningChildrenNotFullyMapped) {
//If there are running child activities not mapped, the call activity must be equally valid in the new model, the activityId in the new model must refer also to a callActivity with matching callElement
FlowElement newModelFlowElement = newModel.getFlowElement(executionActivityId);
if (newModelFlowElement == null) {
throw new FlowableException("Call activity '" + executionActivityId + "' does not exist in the new model. It must be mapped explicitly for migration (or all its child activities)");
}
if (newModelFlowElement instanceof CallActivity) {
if (!referToSameCalledElement((CallActivity) currentModelFlowElement, (CallActivity) newModelFlowElement)) {
throw new FlowableException("Call activity '" + executionActivityId + "' has a different called element in the new model. It must be mapped explicitly for migration (or all its child activities)");
}
if (((CallActivity) currentModelFlowElement).hasMultiInstanceLoopCharacteristics() ^ ((CallActivity) newModelFlowElement).hasMultiInstanceLoopCharacteristics()) {
throw new FlowableException("Call activity '" + executionActivityId + "' loop characteristics differs in new model. It must be mapped explicitly for migration (or all its child activities)");
}
} else {
throw new FlowableException("Call activity '" + executionActivityId + "' is not a Call Activity in the new model. It must be mapped explicitly for migration (or all its child activities)");
}
}
}
String flowElementMultiInstanceParentId = getFlowElementMultiInstanceParentId(currentModelFlowElement);
if (flowElementMultiInstanceParentId != null && mappedFromActivities.contains(flowElementMultiInstanceParentId)) {
// Add the parent MI execution activity Id to be explicitly mapped...
if (!executionActivityIdsToMapExplicitly.contains(flowElementMultiInstanceParentId)) {View on GitHub (pinned to d6d39ce1c6)