flowable/flowable-engine · error · FlowableException
Call activity '" + executionActivityId + "' has a different…
Error message
Call activity '" + executionActivityId + "' has a different called element in the new model. It must be mapped explicitly for migration (or all its child activities)
What it means
Thrown when a call activity with running unmapped child instances exists in both models with the same id, but the called element (the target process definition key) differs between old and new models. Such a change would redirect running children to a different subprocess definition, which Flowable refuses without an explicit mapping.
Solutions
- Add an explicit activity mapping for the call activity in the migration document
- Keep the calledElement unchanged in the target model version
- Terminate/complete running child process instances before migration, then map the activity
- If children should follow the new called element, plan a separate migration of the child instances and map explicitly
Example fix
// before
// new model: <callActivity id="callOrder" calledElement="orderV2"/> while old was orderV1, unmapped
// after
migrationBuilder.addActivityMapping("callOrder", "callOrder"); // explicit mapping allows the change Defensive patterns
Strategy: validation
Validate before calling
CallActivity oldCa = (CallActivity) oldModel.getFlowElement("callTask1");
FlowElement newEl = newModel.getFlowElement("callTask1");
if (newEl instanceof CallActivity && !((CallActivity) newEl).getCalledElement().equals(oldCa.getCalledElement())) {
// add explicit mapping or keep calledElement identical
} Try / catch
try {
migrationBuilder.migrate(instanceId);
} catch (FlowableException e) {
if (e.getMessage().contains("has a different called element")) {
// map the call activity explicitly or revert the calledElement change
}
} Prevention
- Treat calledElement as a stable contract across versions
- Code-review any calledElement change for running instances
- Map call activities explicitly when calledElement intentionally changes
- Document subprocess key renames in release notes
When it happens
Trigger: Migrating instances of a parent process where a call activity's calledElement attribute was changed in the new model version and no explicit activity mapping exists for that call activity.
Common situations: Refactoring the subprocess out or pointing the call activity to a new subprocess key; copy-pasted definition versions where calledElement drifted; renaming the subprocess without mapping.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Call activity '" + executionActivityId + "' does not exist…
- Call activity '" + executionActivityId + "' is not a Call…
- Call activity '" + executionActivityId + "' loop…
- Cannot autoMap activity migration for '" +…
- Cannot complete process instance. Parent process instance
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/f865317241d17ad6.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationManagerImpl.java:698
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)) {
executionActivityIdsToMapExplicitly.add(flowElementMultiInstanceParentId);
}
// The root executions are the ones to migrate and are explicitly mapped
List<ExecutionEntity> miRootExecutions = (List<ExecutionEntity>) executionEntityManager.findInactiveExecutionsByActivityIdAndProcessInstanceId(flowElementMultiInstanceParentId, processInstanceExecution.getId());View on GitHub (pinned to d6d39ce1c6)