flowable/flowable-engine · error · FlowableException

The current flow element of the requested ${execution} is no

Error message

The current flow element of the requested ${execution} is not an ad-hoc sub process

What it means

GetEnabledActivitiesForAdhocSubProcessCmd requires that the execution's current flow element be an AdhocSubProcess. If the execution exists but is parked at any other element (or null element), Flowable throws FlowableException because 'enabled activities' is only meaningful inside an ad-hoc subprocess.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetEnabledActivitiesForAdhocSubProcessCmd.java:50

 */
public class GetEnabledActivitiesForAdhocSubProcessCmd implements Command<List<FlowNode>>, Serializable {

    private static final long serialVersionUID = 1L;
    protected String executionId;

    public GetEnabledActivitiesForAdhocSubProcessCmd(String executionId) {
        this.executionId = executionId;
    }

    @Override
    public List<FlowNode> execute(CommandContext commandContext) {
        ExecutionEntity execution = CommandContextUtil.getExecutionEntityManager(commandContext).findById(executionId);
        if (execution == null) {
            throw new FlowableObjectNotFoundException("No execution found for id '" + executionId + "'", ExecutionEntity.class);
        }

        if (!(execution.getCurrentFlowElement() instanceof AdhocSubProcess adhocSubProcess)) {
            throw new FlowableException("The current flow element of the requested " + execution + " is not an ad-hoc sub process");
        }

        List<FlowNode> enabledFlowNodes = new ArrayList<>();

        // if sequential ordering, only one child execution can be active, so no enabled activities
        if (adhocSubProcess.hasSequentialOrdering()) {
            if (execution.getExecutions().size() > 0) {
                return enabledFlowNodes;
            }
        }

        for (FlowElement flowElement : adhocSubProcess.getFlowElements()) {
            if (flowElement instanceof FlowNode flowNode) {
                if (flowNode.getIncomingFlows().size() == 0) {
                    enabledFlowNodes.add(flowNode);
                }
            }
        }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Locate the execution that is currently inside the ad-hoc subprocess: runtimeService.createExecutionQuery().activityId(adhocSubProcessId).singleResult() and use that execution's id.
  2. Check the process definition to confirm the element is declared as an adHocSubProcess.
  3. Call the API while the ad-hoc subprocess is still active, before it completes.
  4. If you needed dynamic sub-process support instead, use the appropriate APIs rather than the ad-hoc one.

Example fix

// before
runtimeService.getEnabledActivitiesForAdhocSubProcess(processInstanceId);
// after
Execution exec = runtimeService.createExecutionQuery()
    .activityId("myAdhocSubProcess")
    .processInstanceId(processInstanceId)
    .singleResult();
List<FlowNode> nodes = runtimeService.getEnabledActivitiesForAdhocSubProcess(exec.getId());
Defensive patterns

Strategy: validation

Validate before calling

Execution exec = runtimeService.createExecutionQuery()
    .executionId(executionId).singleResult();
// only valid if exec is inside the target ad-hoc subprocess activity

Try / catch

try {
    runtimeService.getEnabledActivitiesForAdhocSubProcess(executionId);
} catch (FlowableException e) {
    // execution is not at an ad-hoc subprocess; look up the correct child execution
}

Prevention

When it happens

Trigger: Calling RuntimeService.getEnabledActivitiesForAdhocSubProcess(executionId) where the execution is not currently inside an ad-hoc subprocess — e.g. it sits at a regular user task, service task, or the process has no ad-hoc subprocess at all.

Common situations: Passing the root process instance execution instead of the child execution positioned inside the ad-hoc subprocess; calling after the ad-hoc subprocess already completed; process model changed so the element is no longer an ad-hoc subprocess; confusion with the similar dynamic-subprocess APIs.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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