{"record":{"id":"f6f5579d05b2b0c8","repo":"flowable/flowable-engine","slug":"programmatic-error-sub-process-behaviour-can-only","errorCode":null,"errorMessage":"Programmatic error: sub process behaviour can only be applied to a SubProcess instance, but got an instance of + flowElement + for + execution","messagePattern":"Programmatic error: sub process behaviour can only be applied to a SubProcess instance, but got an instance of \\+ flowElement \\+ for \\+ execution","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/SubProcessActivityBehavior.java","lineNumber":103,"sourceCode":"                            return startEvent;\n                        }\n                        \n                    } else {\n                        return startEvent;\n                    }\n                }\n            }\n        }\n        return null;\n    }\n\n    protected SubProcess getSubProcessFromExecution(DelegateExecution execution) {\n        FlowElement flowElement = execution.getCurrentFlowElement();\n        SubProcess subProcess = null;\n        if (flowElement instanceof SubProcess) {\n            subProcess = (SubProcess) flowElement;\n        } else {\n            throw new FlowableException(\n                    \"Programmatic error: sub process behaviour can only be applied to a SubProcess instance, but got an instance of \" + flowElement + \" for \"\n                            + execution);\n        }\n        return subProcess;\n    }\n\n    protected Map<String, Object> processDataObjects(Collection<ValuedDataObject> dataObjects) {\n        Map<String, Object> variablesMap = new HashMap<>();\n        // convert data objects to process variables\n        if (dataObjects != null) {\n            for (ValuedDataObject dataObject : dataObjects) {\n                variablesMap.put(dataObject.getName(), dataObject.getValue());\n            }\n        }\n        return variablesMap;\n    }\n}\n","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/SubProcessActivityBehavior.java#L85-L121","documentation":"This is a programmatic/invariant check: the behavior bound to the current flow element must be a SubProcess, but the element resolved from execution.getCurrentFlowElement() is some other FlowElement type. It indicates the execution state and the activity behavior are out of sync, i.e. an internal engine misuse rather than user input.","triggerScenarios":"A DelegateExecution whose currentFlowElement is not an org.flowable.bpmn.model.SubProcess is passed into SubProcessActivityBehavior (e.g. custom code attaching the wrong behavior class to an element, or reusing the behavior outside its intended element type).","commonSituations":"Custom behavior/parse-handler code assigning SubProcessActivityBehavior to a different node type; engine upgrades where execution state changed; reflection-driven testing that feeds the wrong flow element.","solutions":["Ensure the activity behavior for the element is created by the default BehaviorFactory for SubProcess elements, not assigned manually","Verify custom BpmnParseHandler / ActivityBehaviorFactory overrides only apply this behavior to SubProcess instances","Check execution.getCurrentFlowElement() type before invoking the behavior in custom code","If seen during an upgrade, clear the act_ge_bytearray/act_re_procdef of stale deployments and redeploy"],"exampleFix":"// before\nsomeOtherElement.setBehavior(new SubProcessActivityBehavior());\n// after\nif (flowElement instanceof SubProcess) {\n    ((SubProcess) flowElement).setBehavior(new SubProcessActivityBehavior());\n}","handlingStrategy":"type-guard","validationCode":"FlowElement fe = execution.getCurrentFlowElement();\nif (!(fe instanceof SubProcess)) {\n    throw new IllegalStateException(\"Expected SubProcess, got \" + fe.getClass());\n}","typeGuard":"if (execution.getCurrentFlowElement() instanceof SubProcess) { /* safe */ }","tryCatchPattern":"try {\n    subProcessBehavior.execute(execution);\n} catch (FlowableException e) {\n    logger.error(\"Behavior/element mismatch\", e);\n}","preventionTips":["Do not manually assign SubProcessActivityBehavior to non-SubProcess elements","Let the default BehaviorFactory create behaviors","Audit custom BpmnParseHandlers after engine upgrades"],"tags":["subprocess","internal","type-mismatch","bpmn"],"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-14T11:17:12.474Z"}