{"record":{"id":"48e7249abb28bbb9","repo":"flowable/flowable-engine","slug":"multiple-multi-instance-executions-found-for-activ","errorCode":null,"errorMessage":"Multiple multi instance executions found for activity id ","messagePattern":"Multiple multi instance executions found for activity id ","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/AddMultiInstanceExecutionCmd.java","lineNumber":97,"sourceCode":"        if (!multiInstanceLoopCharacteristics.isSequential()) {\n            miExecution.setActive(true);\n            miExecution.setScope(false);\n            \n            childExecution.setCurrentFlowElement(miActivityElement);\n            CommandContextUtil.getAgenda().planContinueMultiInstanceOperation(childExecution, miExecution, currentNumberOfInstances);\n        }\n        \n        return childExecution;\n    }\n    \n    protected ExecutionEntity searchForMultiInstanceActivity(String activityId, String parentExecutionId, ExecutionEntityManager executionEntityManager) {\n        List<ExecutionEntity> childExecutions = executionEntityManager.findChildExecutionsByParentExecutionId(parentExecutionId);\n        \n        ExecutionEntity miExecution = null;\n        for (ExecutionEntity childExecution : childExecutions) {\n            if (activityId.equals(childExecution.getActivityId()) && childExecution.isMultiInstanceRoot()) {\n                if (miExecution != null) {\n                    throw new FlowableException(\"Multiple multi instance executions found for activity id \" + activityId + \" in \" + childExecution);\n                }\n                miExecution = childExecution;\n            }\n            \n            ExecutionEntity childMiExecution = searchForMultiInstanceActivity(activityId, childExecution.getId(), executionEntityManager);\n            if (childMiExecution != null) {\n                if (miExecution != null) {\n                    throw new FlowableException(\"Multiple multi instance executions found for activity id \" + activityId + \" in \" + childExecution);\n                }\n                miExecution = childMiExecution;\n            }\n        }\n        \n        return miExecution;\n    }\n}\n","sourceCodeStart":79,"sourceCodeEnd":114,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/AddMultiInstanceExecutionCmd.java#L79-L114","documentation":"Thrown by AddMultiInstanceExecutionCmd's recursive searchForMultiInstanceActivity when more than one child execution matches the given activityId and is flagged as a multi-instance root. The dynamic-addition API requires exactly one MI root execution per activity id; finding two means the execution tree is ambiguous or corrupted, so the engine refuses to guess which MI root to add the new instance to.","triggerScenarios":"Calling runtimeService.addMultiInstanceExecution(activityId, processInstanceId, executionVariables) when the process contains (or has wrongly persisted) two multi-instance-root executions with the same activity id — e.g. a duplicate MI root left behind by an incomplete termination/compensation, or nested MI inside MI where both parent-scope recursion and child recursion each match the same activity id.","commonSituations":"Historic/dirty runtime data after a failed MI loop cancellation (e.g. terminate end event or boundary event interrupted the MI root deletion); process model changes redeployed over running instances where activity ids collide across nested scopes; manual manipulation or migration of ACT_RU_EXECUTION rows.","solutions":["Inspect ACT_RU_EXECUTION for all rows with the given activity id and MULTI_INSTANCE_ROOT_OF_=1 in the process instance; delete or correct the stale duplicate (only with runtime data expertise and after backing up).","Reproduce and fix the process definition: if nested MI activities share an activity id (or the activityId passed to addMultiInstanceExecution matches both an inner and outer MI), give each MI activity a unique id.","If triggered by cancellation logic, ensure the MI root and its children are fully removed on termination — upgrade Flowable to a version fixing MI deletion on terminate/boundary events.","As a workaround, delete the affected process instance and restart the process from a clean state, migrating business data manually.","Enable debug logging for org.flowable.engine.impl.cmd to trace which executions the search visits before throwing."],"exampleFix":"// before (ambiguous call)\nruntimeService.addMultiInstanceExecution(\"approveTask\", processInstanceId, vars);\n// after (use the exact execution id of the MI root if available)\nExecution miRoot = runtimeService.createExecutionQuery()\n    .processInstanceId(processInstanceId)\n    .activityId(\"approveTask\")\n    .onlyChildExecutions()\n    .singleResult();\nif (miRoot != null) {\n    runtimeService.addMultiInstanceExecution(\"approveTask\", miRoot.getId(), vars);\n}","handlingStrategy":"validation","validationCode":"long count = runtimeService.createExecutionQuery()\n    .processInstanceId(processInstanceId)\n    .activityId(activityId)\n    .count();\nif (count != 1) {\n    throw new IllegalStateException(\"Expected exactly 1 execution for \" + activityId + \", found \" + count);\n}","typeGuard":"boolean hasSingleMiRoot(List<Execution> execs, String activityId) {\n    return execs.stream().filter(e -> activityId.equals(e.getActivityId())).count() == 1;\n}","tryCatchPattern":"try {\n    runtimeService.addMultiInstanceExecution(activityId, processInstanceId, vars);\n} catch (FlowableException e) {\n    if (e.getMessage().startsWith(\"Multiple multi instance executions found\")) {\n        // repair or restart the process instance\n    } else {\n        throw e;\n    }\n}","preventionTips":["Give every multi-instance activity a unique id, especially in nested subprocesses.","Before dynamic MI additions, verify exactly one MI root execution exists via ExecutionQuery.","Ensure terminate/boundary events fully clean up MI roots; keep Flowable updated for MI lifecycle fixes.","Avoid manual edits to ACT_RU_EXECUTION rows; back up before any repair."],"tags":["flowable","multi-instance","process-engine","execution-tree","corrupted-state"],"backgroundTag":"internal-invariant-violation","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}