flowable/flowable-engine · error · FlowableException
Sequential ad-hoc sub process in ${execution} already has an
Error message
Sequential ad-hoc sub process in ${execution} already has an active execution What it means
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.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/ExecuteActivityForAdhocSubProcessCmd.java:59
}
@Override
public Execution 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");
}
FlowNode foundNode = null;
// if sequential ordering, only one child execution can be active
if (adhocSubProcess.hasSequentialOrdering()) {
if (execution.getExecutions().size() > 0) {
throw new FlowableException("Sequential ad-hoc sub process in " + execution + " already has an active execution");
}
}
for (FlowElement flowElement : adhocSubProcess.getFlowElements()) {
if (activityId.equals(flowElement.getId()) && flowElement instanceof FlowNode flowNode) {
if (flowNode.getIncomingFlows().size() == 0) {
foundNode = flowNode;
}
}
}
if (foundNode == null) {
throw new FlowableException("The requested activity with id " + activityId + " can not be enabled in " + execution);
}
ExecutionEntity activityExecution = CommandContextUtil.getExecutionEntityManager().createChildExecution(execution);
activityExecution.setCurrentFlowElement(foundNode);
CommandContextUtil.getAgenda().planContinueProcessOperation(activityExecution);View on GitHub (pinned to d6d39ce1c6)
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
Example fix
// before
managementService.executeCommand(new ExecuteActivityForAdhocSubProcessCmd(execId, nextActivityId));
// after
long active = runtimeService.createExecutionQuery().processInstanceId(pid).count();
if (active == 1) {
managementService.executeCommand(new ExecuteActivityForAdhocSubProcessCmd(execId, nextActivityId));
} Defensive patterns
Strategy: try-catch
Validate before calling
boolean hasActiveChildren = runtimeService.createExecutionQuery().processInstanceId(pid).count() > 1; if (hasActiveChildren && adhoc.isSequential()) return;
Type guard
boolean sequentialAdhocBusy(ExecutionEntity adhocExec) { return adhocExec.getExecutions().size() > 0; } Try / catch
try { ... } catch (FlowableException e) { if (e.getMessage().contains("already has an active execution")) { /* queue the request until current activity completes */ } else throw e; } Prevention
- Gate enablement of sequential ad-hoc activities behind completion listeners
- Debounce/deduplicate client requests
- Switch to parallel ordering in BPMN when concurrency is intended
When it happens
Trigger: 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).
Common situations: 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.
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
- Could not find a scope execution for compensation boundary e
- {workerId} does not hold a lock on the requested job
- Task '' is already claimed by someone else.
- No execution found for id '${executionId}'
- The current flow element of the requested ${execution} is no
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/c4d6057cd719c344.
Report an issue: GitHub.