{"record":{"id":"c4d6057cd719c344","repo":"flowable/flowable-engine","slug":"sequential-ad-hoc-sub-process-in-execution-alre","errorCode":null,"errorMessage":"Sequential ad-hoc sub process in ${execution} already has an active execution","messagePattern":"Sequential ad-hoc sub process in (.+?) already has an active execution","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/ExecuteActivityForAdhocSubProcessCmd.java","lineNumber":59,"sourceCode":"    }\n\n    @Override\n    public Execution execute(CommandContext commandContext) {\n        ExecutionEntity execution = CommandContextUtil.getExecutionEntityManager(commandContext).findById(executionId);\n        if (execution == null) {\n            throw new FlowableObjectNotFoundException(\"No execution found for id '\" + executionId + \"'\", ExecutionEntity.class);\n        }\n\n        if (!(execution.getCurrentFlowElement() instanceof AdhocSubProcess adhocSubProcess)) {\n            throw new FlowableException(\"The current flow element of the requested \" + execution + \" is not an ad-hoc sub process\");\n        }\n\n        FlowNode foundNode = null;\n\n        // if sequential ordering, only one child execution can be active\n        if (adhocSubProcess.hasSequentialOrdering()) {\n            if (execution.getExecutions().size() > 0) {\n                throw new FlowableException(\"Sequential ad-hoc sub process in \" + execution + \" already has an active execution\");\n            }\n        }\n\n        for (FlowElement flowElement : adhocSubProcess.getFlowElements()) {\n            if (activityId.equals(flowElement.getId()) && flowElement instanceof FlowNode flowNode) {\n                if (flowNode.getIncomingFlows().size() == 0) {\n                    foundNode = flowNode;\n                }\n            }\n        }\n\n        if (foundNode == null) {\n            throw new FlowableException(\"The requested activity with id \" + activityId + \" can not be enabled in \" + execution);\n        }\n\n        ExecutionEntity activityExecution = CommandContextUtil.getExecutionEntityManager().createChildExecution(execution);\n        activityExecution.setCurrentFlowElement(foundNode);\n        CommandContextUtil.getAgenda().planContinueProcessOperation(activityExecution);","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/ExecuteActivityForAdhocSubProcessCmd.java#L41-L77","documentation":"In an ad-hoc subprocess with sequential ordering, only one child execution may be active at a time. execute() throws FlowableException when executions already exist under the ad-hoc subprocess, refusing to start a second activity concurrently.","triggerScenarios":"Calling the command to enable another ad-hoc activity while a previously enabled activity in the same sequential ad-hoc subprocess is still running (execution.getExecutions().size() > 0).","commonSituations":"Racing API/service calls that enable ad-hoc activities without waiting for the previous one to finish; UI double-clicks submitting the enable action twice.","solutions":["Wait for the currently active ad-hoc activity to complete before enabling the next one (use a process/task completion listener)","Serialize enablement client-side with a lock/queue or check runtimeService.createExecutionQuery().processInstanceId(pid).active() first","Remove hasSequentialOrdering from the adhocSubProcess in the BPMN if parallel enablement is actually desired"],"exampleFix":"// before\nmanagementService.executeCommand(new ExecuteActivityForAdhocSubProcessCmd(execId, nextActivityId));\n// after\nlong active = runtimeService.createExecutionQuery().processInstanceId(pid).count();\nif (active == 1) {\n    managementService.executeCommand(new ExecuteActivityForAdhocSubProcessCmd(execId, nextActivityId));\n}","handlingStrategy":"try-catch","validationCode":"boolean hasActiveChildren = runtimeService.createExecutionQuery().processInstanceId(pid).count() > 1;\nif (hasActiveChildren && adhoc.isSequential()) return;","typeGuard":"boolean sequentialAdhocBusy(ExecutionEntity adhocExec) { return adhocExec.getExecutions().size() > 0; }","tryCatchPattern":"try { ... } catch (FlowableException e) { if (e.getMessage().contains(\"already has an active execution\")) { /* queue the request until current activity completes */ } else throw e; }","preventionTips":["Gate enablement of sequential ad-hoc activities behind completion listeners","Debounce/deduplicate client requests","Switch to parallel ordering in BPMN when concurrency is intended"],"tags":["flowable","adhoc-subprocess","concurrency"],"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-14T11:17:12.474Z"}