flowable/flowable-engine · error · FlowableException
Plan item could not be found for
Error message
Plan item could not be found for ${planItemInstance} What it means
PlanItemInstanceContainerUtil.isParentCompletionRuleForPlanItemEqualToType inspects the plan item's itemControl to compare its parentCompletionRule type. If the PlanItemInstanceEntity has no PlanItem reference (a degraded/inconsistent state — the runtime instance lost its link to its model element), it throws this FlowableException since the parent completion mode cannot be determined.
Solutions
- Ensure PlanItemInstanceEntity.setPlanItem(definition) is set wherever the entity is created or restored (including custom migration/import code)
- Redeploy/refresh the case definition so runtime plan items resolve their model elements
- Check for engine/version upgrade migration gaps and re-run any missing Flowable migration steps
- If reachable for historic/stale instances, guard the completion logic to skip plan items whose definition is gone after investigating why
Example fix
// before
boolean ignore = PlanItemInstanceContainerUtil.isParentCompletionRuleForPlanItemEqualToType(planItemInstance, ParentCompletionRule.IGNORE);
// after
if (planItemInstance.getPlanItem() == null) {
throw new IllegalStateException("PlanItem definition missing for " + planItemInstance.getId() + "; check deployment/migration");
}
boolean ignore = PlanItemInstanceContainerUtil.isParentCompletionRuleForPlanItemEqualToType(planItemInstance, ParentCompletionRule.IGNORE); Defensive patterns
Strategy: validation
Validate before calling
if (planItemInstance.getPlanItem() == null) {
throw new IllegalStateException("PlanItemInstance " + planItemInstance.getId() + " has no PlanItem definition; deployment/migration issue");
} Type guard
boolean hasPlanItemDefinition(PlanItemInstanceEntity pii) { return pii != null && pii.getPlanItem() != null; } Try / catch
try { return isParentCompletionRuleForPlanItemEqualToType(pii, type); } catch (FlowableException e) { if (e.getMessage().startsWith("Plan item could not be found")) { log.error("Missing plan item definition for {}", pii.getId()); throw new IllegalStateException("Corrupt plan item state", e); } throw e; } Prevention
- Always set the PlanItem definition when constructing/restoring plan item instances
- Re-run engine migrations after Flowable upgrades
- Redeploy case definitions when model elements go missing at runtime
When it happens
Trigger: Calling shouldPlanItemContainerComplete / shouldIgnorePlanItemForCompletion during case completion evaluation when a planItemInstance.getPlanItem() is null — e.g. after partial engine state, an inconsistent upgrade, or a plan item instance built without its definition attached.
Common situations: Custom code creating or migrating PlanItemInstanceEntity instances without setting the PlanItem definition; corrupted/incompletely deployed case definitions after a model change; recompletion of historic plan items.
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
- Can only trigger a plan item that is in the ACTIVE state
- Cannot find plan item instance for id
- Cannot find plan item instance with id
- Cannot find plan item with definition id
- Could not resolve case instance id
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/aab40e7abe0a84e2.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/util/PlanItemInstanceContainerUtil.java:221
for (PlanItemInstanceEntity item : planItemInstances) {
if (Objects.equals(planItemInstance.getStageInstanceId(), item.getStageInstanceId()) && COMPLETED.equals(item.getState())) {
return true;
}
}
}
return false;
}
/**
* Checks the plan items parent completion mode to be equal to a given type and returns true if so.
*
* @param planItemInstance the plan item to check for a parent completion mode
* @param parentCompletionRuleType the parent completion type to check against
* @return true, if there is a parent completion mode set on the plan item equal to the given one
*/
public static boolean isParentCompletionRuleForPlanItemEqualToType(PlanItemInstanceEntity planItemInstance, String parentCompletionRuleType) {
if (planItemInstance.getPlanItem() == null) {
throw new FlowableException("Plan item could not be found for " + planItemInstance);
}
if (planItemInstance.getPlanItem().getItemControl() != null && planItemInstance.getPlanItem().getItemControl().getParentCompletionRule() != null) {
ParentCompletionRule parentCompletionRule = planItemInstance.getPlanItem().getItemControl().getParentCompletionRule();
if (parentCompletionRuleType.equals(parentCompletionRule.getType())) {
return true;
}
}
return false;
}
}
View on GitHub (pinned to d6d39ce1c6)