flowable/flowable-engine · error · FlowableException
From activity '" + Arrays.toString(duplicates.toArray()) +…
Error message
From activity '" + Arrays.toString(duplicates.toArray()) + "' is mapped more than once
What it means
A migration document maps source activities to target activities; each source ('from') activity id may appear at most once. setActivityMigrationMappings detects duplicates across the supplied mappings and throws FlowableException listing the duplicated ids, preventing ambiguous migration instructions.
Solutions
- Deduplicate mappings by fromActivityId before setting them.
- Merge multiple targets of the same source activity into a single mapping with multiple target activity ids where supported.
- Review the duplicated ids in the message and remove the redundant mapping.
Example fix
// before
mappings.add(fromActivity("userTask1").toActivity("userTaskA"));
mappings.add(fromActivity("userTask1").toActivity("userTaskB"));
// after
mappings.add(fromActivity("userTask1").toActivity("userTaskA")); // keep only one mapping per from-activity Defensive patterns
Strategy: validation
Validate before calling
Set<String> seen = new HashSet<>();
for (ActivityMigrationMapping m : mappings) {
if (!seen.add(m.getFromActivityId())) throw new IllegalStateException("duplicate from-activity: " + m.getFromActivityId());
} Try / catch
try {
document.setActivityMigrationMappings(mappings);
} catch (FlowableException e) {
logger.error("Duplicate activity mappings: " + e.getMessage());
} Prevention
- Deduplicate mapping lists by fromActivityId before building
- Centralize mapping construction so mappings aren't added twice
- Validate merged mapping lists before applying them
When it happens
Trigger: Calling setActivityMigrationMappings (typically via the builder's withActivityMappings during build) where two or more ActivityMigrationMapping entries have the same fromActivityId.
Common situations: Programmatically generating mappings in a loop that adds the same source activity twice; merging mapping lists from different sources; copy-paste editing migration mapping definitions.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot find the process definition to migrate to…
- Cannot find the process to migrate, with id" +…
- Not implemented yet!!!
- Set of process instance ids is null
- A process instance id is required, but the provided id '" +…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/7edc805ae1bc7c3f.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationDocumentImpl.java:213
}
@Override
public String getPostUpgradeJavaDelegate() {
return postUpgradeJavaDelegate;
}
@Override
public String getPostUpgradeJavaDelegateExpression() {
return postUpgradeJavaDelegateExpression;
}
public void setActivityMigrationMappings(List<ActivityMigrationMapping> activityMigrationMappings) {
List<String> duplicates = findDuplicatedFromActivityIds(activityMigrationMappings);
if (duplicates.isEmpty()) {
this.activityMigrationMappings = activityMigrationMappings;
this.activitiesLocalVariables = buildActivitiesLocalVariablesMap(activityMigrationMappings);
} else {
throw new FlowableException("From activity '" + Arrays.toString(duplicates.toArray()) + "' is mapped more than once");
}
}
public void setEnableActivityMappings(List<EnableActivityMapping> enableActivityMappings) {
this.enableActivityMappings = enableActivityMappings;
}
protected static List<String> findDuplicatedFromActivityIds(List<ActivityMigrationMapping> activityMigrationMappings) {
//Frequency Map
Map<String, Long> frequencyMap = activityMigrationMappings.stream()
.filter(mapping -> !mapping.isToParentProcess())
.flatMap(mapping -> mapping.getFromActivityIds().stream())
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
//Duplicates
List<String> duplicatedActivityIds = frequencyMap.entrySet()
.stream()
.filter(entry -> entry.getValue() > 1)View on GitHub (pinned to d6d39ce1c6)