flowable/flowable-engine · error · FlowableException

Could not find a FlowElement for activityId

Error message

Could not find a FlowElement for activityId <activityId> in <execution>

What it means

DelegateHelper.getFlowElement resolves the BpmnModel FlowElement matching the execution's current activityId. When the model contains no element for that activityId, Flowable throws this FlowableException rather than returning null, since delegate code cannot proceed without the element definition.

Solutions

  1. Verify the activityId exists in the deployed process definition's BpmnModel (inspect the BPMN XML / model)
  2. Check that the execution's process definition version matches the model you expect; redeploy the correct BPMN resource
  3. Ensure DelegateHelper.getFlowElement is only invoked from code running inside a real flow-element execution (execution listener, task listener, delegate on an activity)
  4. Guard by catching FlowableException and falling back to execution.getCurrentFlowElement() if available

Example fix

// before
FlowElement el = DelegateHelper.getFlowElement(execution);
// after
FlowElement el = execution.getCurrentFlowElement();
if (el == null) {
    el = DelegateHelper.getFlowElement(execution); // only when safe
}
Defensive patterns

Strategy: try-catch

Validate before calling

boolean ok = execution.getCurrentActivityId() != null && execution.getCurrentFlowElement() != null;

Type guard

function hasFlowElement(exec) { return exec.getCurrentFlowElement && exec.getCurrentFlowElement() != null; }

Try / catch

try { FlowElement el = DelegateHelper.getFlowElement(execution); ... } catch (FlowableException e) { logger.warn("No FlowElement for activityId " + execution.getCurrentActivityId()); }

Prevention

When it happens

Trigger: Calling DelegateHelper.getFlowElement(execution) (directly or via flowElement()/getFlowElementExtensionElements()) when execution.getCurrentActivityId() does not exist in the process definition's BpmnModel — e.g. a delegate/listener executing for an activity not present in the deployed model, or a stale/mismatched process definition version.

Common situations: Dynamic model modification or incomplete BpmnModel deployment; executing a delegate in a context (like an async job or migration) where the cached model differs from the deployed one; typo'd or programmatically-injected activity ids; using DelegateHelper outside an actual flow-element execution context.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/411746043ea7b607. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/delegate/DelegateHelper.java:84

    /**
     * Returns the {@link BpmnModel} matching the process definition bpmn model for the process definition of the passed {@link DelegateExecution}.
     */
    public static BpmnModel getBpmnModel(DelegateExecution execution) {
        if (execution == null) {
            throw new FlowableException("Null execution passed");
        }
        return ProcessDefinitionUtil.getBpmnModel(execution.getProcessDefinitionId());
    }

    /**
     * Returns the current {@link FlowElement} where the {@link DelegateExecution} is currently at.
     */
    public static FlowElement getFlowElement(DelegateExecution execution) {
        BpmnModel bpmnModel = getBpmnModel(execution);
        FlowElement flowElement = bpmnModel.getFlowElement(execution.getCurrentActivityId());
        if (flowElement == null) {
            throw new FlowableException("Could not find a FlowElement for activityId " + execution.getCurrentActivityId() + " in " + execution);
        }
        return flowElement;
    }

    /**
     * Returns whether or not the provided execution is being use for executing an {@link ExecutionListener}.
     */
    public static boolean isExecutingExecutionListener(DelegateExecution execution) {
        return execution.getCurrentFlowableListener() != null;
    }

    /**
     * Returns for the activityId of the passed {@link DelegateExecution} the {@link Map} of {@link ExtensionElement} instances. These represent the extension elements defined in the BPMN 2.0 XML as
     * part of that particular activity.
     * 
     * If the execution is currently being used for executing an {@link ExecutionListener}, the extension elements of the listener will be used. Use the
     * {@link #getFlowElementExtensionElements(DelegateExecution)} or {@link #getListenerExtensionElements(DelegateExecution)} instead to specifically get the extension elements of either the flow
     * element or the listener.

View on GitHub (pinned to d6d39ce1c6)