{"record":{"id":"07dfa717ff6b0a3b","repo":"flowable/flowable-engine","slug":"sequenceflowid-does-not-match-a-sequence-flow-f","errorCode":null,"errorMessage":"${sequenceFlowId} does not match a sequence flow for ${delegateExecution}","messagePattern":"(.+?) does not match a sequence flow for (.+?)","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/delegate/DelegateHelper.java","lineNumber":63,"sourceCode":"    /**\n     * To be used in an {@link ActivityBehavior} or {@link JavaDelegate}: leaves according to the default BPMN 2.0 rules: all sequenceflow with a condition that evaluates to true are followed.\n     */\n    public static void leaveDelegate(DelegateExecution delegateExecution) {\n        CommandContextUtil.getAgenda().planTakeOutgoingSequenceFlowsOperation((ExecutionEntity) delegateExecution, true);\n    }\n\n    /**\n     * To be used in an {@link ActivityBehavior} or {@link JavaDelegate}: leaves the current activity via one specific sequenceflow.\n     */\n    public static void leaveDelegate(DelegateExecution delegateExecution, String sequenceFlowId) {\n        String processDefinitionId = delegateExecution.getProcessDefinitionId();\n        org.flowable.bpmn.model.Process process = ProcessDefinitionUtil.getProcess(processDefinitionId);\n        FlowElement flowElement = process.getFlowElement(sequenceFlowId);\n        if (flowElement instanceof SequenceFlow) {\n            delegateExecution.setCurrentFlowElement(flowElement);\n            CommandContextUtil.getAgenda().planTakeOutgoingSequenceFlowsOperation((ExecutionEntity) delegateExecution, false);\n        } else {\n            throw new FlowableException(sequenceFlowId + \" does not match a sequence flow for \" + delegateExecution);\n        }\n    }\n\n    /**\n     * Returns the {@link BpmnModel} matching the process definition bpmn model for the process definition of the passed {@link DelegateExecution}.\n     */\n    public static BpmnModel getBpmnModel(DelegateExecution execution) {\n        if (execution == null) {\n            throw new FlowableException(\"Null execution passed\");\n        }\n        return ProcessDefinitionUtil.getBpmnModel(execution.getProcessDefinitionId());\n    }\n\n    /**\n     * Returns the current {@link FlowElement} where the {@link DelegateExecution} is currently at.\n     */\n    public static FlowElement getFlowElement(DelegateExecution execution) {\n        BpmnModel bpmnModel = getBpmnModel(execution);","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/delegate/DelegateHelper.java#L45-L81","documentation":"DelegateHelper.leaveDelegate() resolves the execution's currentFlowElement as a sequenceFlowId from the BPMN model of the process definition. If the looked-up FlowElement is not a SequenceFlow (or is missing), Flowable throws this error, because it can only take outgoing flows when positioned on a sequence flow.","triggerScenarios":"Calling DelegateHelper.leaveDelegate(delegateExecution) while the delegate execution's currentFlowElement id (sequenceFlowId) does not exist in the process definition, or points to a different element type (task, event, gateway).","commonSituations":"Executing leaveDelegate from a listener/execution-logic attached to a node rather than to a sequence flow; changing the BPMN XML (renaming/removing the flow id) while old deployed process instances still run with cached state; copying delegate code between process models.","solutions":["Only invoke leaveDelegate when the execution is on a SequenceFlow (e.g. an execution listener attached to the sequence flow element)","Check the currentFlowElement id exists in the current process definition's BPMN model before calling","For logic on a node, use the appropriate agenda operation (planTakeOutgoingSequenceFlowsOperation on the activity) or DelegateHelper methods meant for flow elements","Redeploy consistent model versions so running instances match the deployed definitions"],"exampleFix":"// before\npublic void execute(DelegateExecution execution) {\n    DelegateHelper.leaveDelegate(execution); // executed on a ServiceTask\n}\n\n// after: attach to the sequence flow, or guard\nFlowElement el = execution.getCurrentFlowElement();\nif (el instanceof SequenceFlow) {\n    DelegateHelper.leaveDelegate(execution);\n}","handlingStrategy":"type-guard","validationCode":"FlowElement el = execution.getCurrentFlowElement();\nboolean isSequenceFlow = el != null && el.getId() != null\n    && ProcessDefinitionUtil.getProcessDefinition(execution.getProcessDefinitionId()) != null\n    && DelegateHelper.getBpmnModel(execution).getMainProcess().getFlowElement(el.getId()) instanceof SequenceFlow;","typeGuard":"boolean canLeaveDelegate(DelegateExecution e) {\n    FlowElement el = e.getCurrentFlowElement();\n    return el instanceof SequenceFlow;\n}","tryCatchPattern":"try {\n    DelegateHelper.leaveDelegate(execution);\n} catch (FlowableException e) {\n    if (e.getMessage().contains(\"does not match a sequence flow\")) {\n        // wrong element type: route logic to the appropriate node/flow listener\n    } else throw e;\n}","preventionTips":["Attach leaveDelegate-style logic only to sequence-flow execution listeners","Keep flow element ids stable across model versions, or redeploy matching versions together"],"tags":["flowable","bpmn","delegate","workflow"],"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-14T05:17:10.506Z"}