flowable/flowable-engine · error · FlowableException
multiple active or enabled plan item instances found for pla
Error message
multiple active or enabled plan item instances found for plan item definition <planItemDefinitionId>
What it means
During a plan item state change to AVAILABLE, Flowable expects at most one active or enabled plan item instance per plan item definition mapping. When two or more instances of the same plan item definition are simultaneously active or enabled, the operation is ambiguous, so this FlowableException is thrown.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/AbstractCmmnDynamicStateManager.java:427
if (planItemDefinitionMapping.getWithLocalVariables() != null && !planItemDefinitionMapping.getWithLocalVariables().isEmpty()) {
availablePlanItemInstance.setVariablesLocal(planItemDefinitionMapping.getWithLocalVariables());
}
CmmnHistoryManager cmmnHistoryManager = cmmnEngineConfiguration.getCmmnHistoryManager();
cmmnHistoryManager.recordPlanItemInstanceCreated(availablePlanItemInstance);
CmmnEngineAgenda agenda = CommandContextUtil.getAgenda(commandContext);
agenda.planChangePlanItemInstanceToAvailableOperation(availablePlanItemInstance);
continue;
}
PlanItemInstance existingPlanItemInstance = null;
boolean allExistingPlanItemsAreAvailable = true;
for (PlanItemInstance planItemInstance : planItemInstances) {
if (PlanItemInstanceState.ACTIVE.equals(planItemInstance.getState()) || PlanItemInstanceState.ENABLED.equals(planItemInstance.getState())) {
if (existingPlanItemInstance != null) {
throw new FlowableException("multiple active or enabled plan item instances found for plan item definition " + planItemDefinitionMapping.getPlanItemDefinitionId());
} else {
existingPlanItemInstance = planItemInstance;
}
}
if (!PlanItemInstanceState.AVAILABLE.equals(planItemInstance.getState())) {
allExistingPlanItemsAreAvailable = false;
}
}
if (allExistingPlanItemsAreAvailable) {
// all existing plan items are available, we can continue without any changes
continue;
}
if (existingPlanItemInstance == null) {
throw new FlowableException("No active or enabled plan item instances found for plan item definition " + planItemDefinitionMapping.getPlanItemDefinitionId());
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Complete or disable the duplicate active/enabled instances first so only one remains, then retry the state change
- Use movePlanItemInstance(s) targeting specific plan item instance ids rather than definition-level mapping
- Query PlanItemInstanceQuery for the planItemDefinitionId to inspect the duplicates and resolve them
- Restructure the case model (e.g. stage/milestone boundaries) to avoid multiple concurrent instances
Example fix
// before
changeState.addPlanItemDefinitionMapping(
new SimplePlanItemDefinitionMapping.Builder().planItemDefinitionId("taskDef").build()); // ambiguous
// after
List<PlanItemInstance> pis = cmmnRuntimeService.createPlanItemInstanceQuery()
.planItemDefinitionId("taskDef").caseInstanceId(caseId).list();
// move only the specific instance
changeState.addPlanItemInstanceMapping(
new SimplePlanItemInstanceMapping.Builder().planItemId(pis.get(0).getId()).build()); Defensive patterns
Strategy: validation
Validate before calling
long active = cmmnRuntimeService.createPlanItemInstanceQuery()
.caseInstanceId(caseInstanceId).planItemDefinitionId(defId)
.list().stream()
.filter(p -> PlanItemInstanceState.ACTIVE.equals(p.getState()) || PlanItemInstanceState.ENABLED.equals(p.getState()))
.count();
if (active > 1) throw new IllegalStateException("Ambiguous move: " + active + " active/enabled instances"); Try / catch
try {
cmmnRuntimeService.changePlanItemState(caseInstanceId, changeState);
} catch (FlowableException e) {
if (e.getMessage().startsWith("multiple active or enabled plan item instances")) {
// fall back to instance-id based move
} else {
throw e;
}
} Prevention
- Query plan item instances before definition-level state changes
- Prefer movePlanItemInstance(s)To... with explicit instance ids when duplicates may exist
- Model multi-occurrence cases so at most one instance is enabled at a time
When it happens
Trigger: Calling changePlanItemState / changePlanItemInstancesToAvailableState when multiple plan item instances for the same planItemDefinitionId are in ACTIVE or ENABLED state, e.g. multi-instance-like repeated tasks or several enabled tasks of the same definition.
Common situations: Cases where a human task plan item was completed and re-created multiple times leaving several enabled instances; attempting a bulk state move on a plan item that occurs multiple times in the model; user event listeners enabled repeatedly.
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
- No active or enabled plan item instances found for plan item
- Plan item instance for {eventSubscription} can not be found
- Could not find plan item instance for plan item with definit
- Can only trigger a plan item that is in the ACTIVE state
- Cannot trigger a plan item which activity behavior does not
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/295ef36134d1997d.
Report an issue: GitHub.