{"record":{"id":"b9cd4f7f43dc12d7","repo":"flowable/flowable-engine","slug":"duplicate-activity-id-activityid","errorCode":null,"errorMessage":"duplicate activity id '${activityId}'","messagePattern":"duplicate activity id '(.+?)'","errorType":"exception","errorClass":"PvmException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/pvm/process/ScopeImpl.java","lineNumber":66,"sourceCode":"        }\n        for (ActivityImpl activity : activities) {\n            ActivityImpl nestedActivity = activity.findActivity(activityId);\n            if (nestedActivity != null) {\n                return nestedActivity;\n            }\n        }\n        return null;\n    }\n\n    public ActivityImpl createActivity() {\n        return createActivity(null);\n    }\n\n    public ActivityImpl createActivity(String activityId) {\n        ActivityImpl activity = new ActivityImpl(activityId, processDefinition);\n        if (activityId != null) {\n            if (processDefinition.findActivity(activityId) != null) {\n                throw new PvmException(\"duplicate activity id '\" + activityId + \"'\");\n            }\n            namedActivities.put(activityId, activity);\n        }\n        activity.setParent(this);\n        activities.add(activity);\n        return activity;\n    }\n\n    public boolean contains(ActivityImpl activity) {\n        if (namedActivities.containsKey(activity.getId())) {\n            return true;\n        }\n        for (ActivityImpl nestedActivity : activities) {\n            if (nestedActivity.contains(activity)) {\n                return true;\n            }\n        }\n        return false;","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/pvm/process/ScopeImpl.java#L48-L84","documentation":"PvmException thrown by ScopeImpl.createActivity when an activity id is provided that already exists in the process definition. Activity ids must be unique within the whole definition, since findActivity and namedActivities rely on global uniqueness. Null ids are allowed (anonymous activities) and are not checked.","triggerScenarios":"Creating two activities with the same id on the same (or nested) scope, or the builder's activity(id) helper invoked twice with the same id before buildProcessDefinition.","commonSituations":"Duplicate element ids in BPMN XML, merging two models into one definition, or loops in a generator that reuse ids.","solutions":["Use unique activity ids across the entire process definition.","Fix duplicate ids in the BPMN source before deployment.","Generate unique ids programmatically (e.g. prefix per sub-scope or use a counter/UUID) when building dynamically."],"exampleFix":"// before\nscope.createActivity(\"taskA\");\nscope.createActivity(\"taskA\"); // duplicate\n// after\nscope.createActivity(\"taskA\");\nscope.createActivity(\"taskB\"); // unique id","handlingStrategy":"validation","validationCode":"if (definition.findActivity(activityId) != null) {\n  throw new IllegalArgumentException(\"activity id '\" + activityId + \"' already exists in this process definition\");\n}\nscope.createActivity(activityId);","typeGuard":null,"tryCatchPattern":"try {\n  scope.createActivity(activityId);\n} catch (PvmException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"duplicate activity id\")) {\n    // rekey or skip the activity\n    scope.createActivity(activityId + \"_2\");\n  }\n}","preventionTips":["Use globally unique ids (namespace by diagram/model id) when merging models.","Run BPMN id-uniqueness validation in CI before deployment."],"tags":["java","pvm","duplicate-id","process-model"],"backgroundTag":"invalid-identifier-format","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"}