{"record":{"id":"7edc805ae1bc7c3f","repo":"flowable/flowable-engine","slug":"from-activity-arrays-tostring-duplicates-toar","errorCode":null,"errorMessage":"From activity '\" + Arrays.toString(duplicates.toArray()) + \"' is mapped more than once","messagePattern":"From activity '\" \\+ Arrays\\.toString\\(duplicates\\.toArray\\(\\)\\) \\+ \"' is mapped more than once","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationDocumentImpl.java","lineNumber":213,"sourceCode":"    }\n\n    @Override\n    public String getPostUpgradeJavaDelegate() {\n        return postUpgradeJavaDelegate;\n    }\n\n    @Override\n    public String getPostUpgradeJavaDelegateExpression() {\n        return postUpgradeJavaDelegateExpression;\n    }\n\n    public void setActivityMigrationMappings(List<ActivityMigrationMapping> activityMigrationMappings) {\n        List<String> duplicates = findDuplicatedFromActivityIds(activityMigrationMappings);\n        if (duplicates.isEmpty()) {\n            this.activityMigrationMappings = activityMigrationMappings;\n            this.activitiesLocalVariables = buildActivitiesLocalVariablesMap(activityMigrationMappings);\n        } else {\n            throw new FlowableException(\"From activity '\" + Arrays.toString(duplicates.toArray()) + \"' is mapped more than once\");\n        }\n    }\n    \n    public void setEnableActivityMappings(List<EnableActivityMapping> enableActivityMappings) {\n        this.enableActivityMappings = enableActivityMappings;\n    }\n\n    protected static List<String> findDuplicatedFromActivityIds(List<ActivityMigrationMapping> activityMigrationMappings) {\n        //Frequency Map\n        Map<String, Long> frequencyMap = activityMigrationMappings.stream()\n            .filter(mapping -> !mapping.isToParentProcess())\n            .flatMap(mapping -> mapping.getFromActivityIds().stream())\n            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));\n\n        //Duplicates\n        List<String> duplicatedActivityIds = frequencyMap.entrySet()\n            .stream()\n            .filter(entry -> entry.getValue() > 1)","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationDocumentImpl.java#L195-L231","documentation":"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.","triggerScenarios":"Calling setActivityMigrationMappings (typically via the builder's withActivityMappings during build) where two or more ActivityMigrationMapping entries have the same fromActivityId.","commonSituations":"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.","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."],"exampleFix":"// before\nmappings.add(fromActivity(\"userTask1\").toActivity(\"userTaskA\"));\nmappings.add(fromActivity(\"userTask1\").toActivity(\"userTaskB\"));\n\n// after\nmappings.add(fromActivity(\"userTask1\").toActivity(\"userTaskA\")); // keep only one mapping per from-activity","handlingStrategy":"validation","validationCode":"Set<String> seen = new HashSet<>();\nfor (ActivityMigrationMapping m : mappings) {\n    if (!seen.add(m.getFromActivityId())) throw new IllegalStateException(\"duplicate from-activity: \" + m.getFromActivityId());\n}","typeGuard":null,"tryCatchPattern":"try {\n    document.setActivityMigrationMappings(mappings);\n} catch (FlowableException e) {\n    logger.error(\"Duplicate activity mappings: \" + e.getMessage());\n}","preventionTips":["Deduplicate mapping lists by fromActivityId before building","Centralize mapping construction so mappings aren't added twice","Validate merged mapping lists before applying them"],"tags":["java","flowable","migration","duplicate-mapping"],"backgroundTag":"invalid-argument-value","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}