{"record":{"id":"fb7fd38ea4069b1e","repo":"flowable/flowable-engine","slug":"joining-scope-executions-is-not-allowed","errorCode":null,"errorMessage":"joining scope executions is not allowed","messagePattern":"joining scope executions is not allowed","errorType":"exception","errorClass":"PvmException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/ExecutionEntity.java","lineNumber":553,"sourceCode":"            childExecutions.add(childExecution);\n            childExecutions.addAll(childExecution.getAllChildExecutions());\n        }\n        return childExecutions;\n    }\n\n    @Override\n    @SuppressWarnings({\"unchecked\", \"rawtypes\"})\n    public void takeAll(List<PvmTransition> transitions, List<ActivityExecution> recyclableExecutions) {\n\n        fireActivityCompletedEvent();\n\n        transitions = new ArrayList<>(transitions);\n        recyclableExecutions = (recyclableExecutions != null ? new ArrayList<>(recyclableExecutions) : new ArrayList<>());\n\n        if (recyclableExecutions.size() > 1) {\n            for (ActivityExecution recyclableExecution : recyclableExecutions) {\n                if (((ExecutionEntity) recyclableExecution).isScope()) {\n                    throw new PvmException(\"joining scope executions is not allowed\");\n                }\n            }\n        }\n\n        ExecutionEntity concurrentRoot = ((isConcurrent && !isScope) ? getParent() : this);\n        List<ExecutionEntity> concurrentActiveExecutions = new ArrayList<>();\n        List<ExecutionEntity> concurrentInActiveExecutions = new ArrayList<>();\n        for (ExecutionEntity execution : concurrentRoot.getExecutions()) {\n            if (execution.isActive()) {\n                concurrentActiveExecutions.add(execution);\n            } else {\n                concurrentInActiveExecutions.add(execution);\n            }\n        }\n\n        if (LOGGER.isDebugEnabled()) {\n            LOGGER.debug(\"transitions to take concurrent: {}\", transitions);\n            LOGGER.debug(\"active concurrent executions: {}\", concurrentActiveExecutions);","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/ExecutionEntity.java#L535-L571","documentation":"Flowable/Activiti's process model concurrency (parallel gateway / multi-instance) joins multiple incoming executions into one. When more than one incoming execution arrives and any of them is a scope execution (an execution that carries local variables/its own variable scope), the engine cannot merge them and throws this PvmException. This is an internal BPMN modeling constraint enforced at runtime during transition taking.","triggerScenarios":"Calling takeAll with recyclableExecutions.size() > 1 where at least one incoming execution has isScope()==true; typically a parallel/inclusive gateway or merge activity whose incoming flows originate from scope-creating activities (e.g. embedded subprocess call activities or activities with local scoped executions).","commonSituations":"BPMN models where a parallel gateway joins flows coming out of embedded subprocesses or call activities; using an inclusive gateway to merge scope executions; models migrated from older engine versions that previously tolerated scope joins.","solutions":["Redesign the BPMN model so parallel flows that converge pass through non-scope executions; end each branch with an end event inside its scope so the scope terminates before joining.","Place a parallel gateway before the subprocess exit so the scope execution ends and a fresh non-scope execution continues to the joining gateway.","If branches carry local variables, move those variables to a parent scope or copy them explicitly before the join.","Upgrade/verify engine version: newer Flowable versions handle some scope joins; check release notes for gateway/scope join fixes."],"exampleFix":"// before: branches out of embedded subprocesses converge directly on one parallel gateway\n<parallelGateway id=\"join\"/>\n... <sequenceFlow sourceRef=\"subprocess1\" targetRef=\"join\"/>\n\n// after: terminate each scope with an end event, then join\n<subprocess id=\"sub1\"><endEvent id=\"sub1End\"/>...</subprocess>\n<sequenceFlow sourceRef=\"sub1\" targetRef=\"join\"/>","handlingStrategy":"validation","validationCode":"// Model check: ensure no join gateway directly follows an embedded subprocess/callActivity without an intervening end event\nboolean joinsScopeExit = bpmnModel.getGateways().stream()\n    .anyMatch(g -> g.getIncomingFlows().stream()\n        .anyMatch(f -> isScopeCreatingActivity(bpmnModel, f.getSourceRef())));\nif (joinsScopeExit) throw new ModelValidationException(\"parallel gateway joins scope executions\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Terminate subprocess branches with end events before converging on join gateways","Validate BPMN models with the model's validation API at deployment time","Keep local variables out of branch scopes that later merge, or copy them up beforehand"],"tags":["bpmn","process-model","concurrency","scope"],"backgroundTag":"invalid-state-transition","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"}