flowable/flowable-engine · error · FlowableException

Plan item could not be found for

Error message

Plan item could not be found for <elementId>

What it means

While verifying satisfied sentry parts during a plan item state change, an AVAILABLE plan item instance that has matched sentry parts must have its PlanItem model reference; if getPlanItem() is null the engine cannot evaluate entry criteria and throws this FlowableException. This indicates an internal model resolution failure.

Solutions

  1. Redeploy the case definition containing the referenced elementId so the model can be resolved
  2. Migrate the case instance to a definition containing the element before doing dynamic state changes
  3. Check the case instance's case definition id vs the deployed model for version mismatch
  4. Clear/repair the inconsistent plan item instance rows for the case instance

Example fix

// before
cmmnRuntimeService.changePlanItemState(caseInstanceId, oldChangeState); // targets stale definition
// after
cmmnRuntimeService.setCaseInstanceCaseDefinition(caseInstanceId, newCaseDefinitionId); // or migrate first
cmmnRuntimeService.changePlanItemState(caseInstanceId, changeState);
Defensive patterns

Strategy: try-catch

Validate before calling

if (planItemInstanceEntity.getPlanItem() == null) {
    throw new IllegalStateException("Plan item model unresolved for element " + planItemInstanceEntity.getElementId());
}

Type guard

boolean hasResolvedPlanItem(PlanItemInstance pi) {
    return pi instanceof PlanItemInstanceEntity e && e.getPlanItem() != null;
}

Try / catch

try {
    cmmnRuntimeService.changePlanItemState(caseInstanceId, changeState);
} catch (FlowableException e) {
    if (e.getMessage().startsWith("Plan item could not be found")) {
        // migrate case instance to a definition containing the element, then retry
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: doMovePlanItemState / executeVerifySatisfiedSentryParts with an AVAILABLE plan item instance whose planItem reference is null (model lookup failed for the elementId) while sentry parts were satisfied.

Common situations: Corrupted or partially migrated case instance data referencing plan item ids absent from the deployed case definition; changing state across case definition versions where the element no longer exists.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/AbstractCmmnDynamicStateManager.java:614

                sentryInstanceMap.put(sentryPartInstanceEntity.getPlanItemInstanceId(), new ArrayList<>());
            }
            
            sentryInstanceMap.get(sentryPartInstanceEntity.getPlanItemInstanceId()).add(sentryPartInstanceEntity);
        }
        
        PlanItemInstanceEntityManager planItemInstanceEntityManager = cmmnEngineConfiguration.getPlanItemInstanceEntityManager();
        List<PlanItemInstanceEntity> planItemInstances = planItemInstanceEntityManager.findByCaseInstanceId(caseInstance.getId());
        
        CmmnDeploymentManager deploymentManager = cmmnEngineConfiguration.getDeploymentManager();
        CmmnModel targetCmmnModel = deploymentManager.resolveCaseDefinition(caseInstanceChangeState.getCaseDefinitionToMigrateTo()).getCmmnModel();
        
        for (PlanItemInstanceEntity planItemInstanceEntity : planItemInstances) {
            List<String> skipSentryPartInstanceForDeleteIds = new ArrayList<>();
            if (PlanItemInstanceState.AVAILABLE.equalsIgnoreCase(planItemInstanceEntity.getState()) && 
                    sentryInstanceMap.containsKey(planItemInstanceEntity.getId())) {
                
                if (planItemInstanceEntity.getPlanItem() == null) {
                    throw new FlowableException("Plan item could not be found for " + planItemInstanceEntity.getElementId());
                }
                
                if (planItemInstanceEntity.getPlanItem().getEntryCriteria().isEmpty()) {
                    continue;
                }
                
                for (Criterion criterion : planItemInstanceEntity.getPlanItem().getEntryCriteria()) {
                    verifySatisfiedSentryPartsForCriterion(criterion, planItemInstanceEntity, sentryInstanceMap, 
                            skipSentryPartInstanceForDeleteIds, false, targetCmmnModel, sentryPartInstanceEntityManager);
                }
                
            } else if (PlanItemInstanceState.ACTIVE.equalsIgnoreCase(planItemInstanceEntity.getState()) && 
                    sentryInstanceMap.containsKey(planItemInstanceEntity.getId())) {
                
                if (planItemInstanceEntity.getPlanItem() == null) {
                    throw new FlowableException("Plan item could not be found for " + planItemInstanceEntity.getElementId());
                }
                

View on GitHub (pinned to d6d39ce1c6)