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

  1. Ensure PlanItemInstanceEntity.setPlanItem(definition) is set wherever the entity is created or restored (including custom migration/import code)
  2. Redeploy/refresh the case definition so runtime plan items resolve their model elements
  3. Check for engine/version upgrade migration gaps and re-run any missing Flowable migration steps
  4. 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

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


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)