{"record":{"id":"3a590151aaa59f3d","repo":"flowable/flowable-engine","slug":"plan-item-could-not-be-found-for-elementid","errorCode":null,"errorMessage":"Plan item could not be found for <elementId>","messagePattern":"Plan item could not be found for <elementId>","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/AbstractCmmnDynamicStateManager.java","lineNumber":614,"sourceCode":"                sentryInstanceMap.put(sentryPartInstanceEntity.getPlanItemInstanceId(), new ArrayList<>());\n            }\n            \n            sentryInstanceMap.get(sentryPartInstanceEntity.getPlanItemInstanceId()).add(sentryPartInstanceEntity);\n        }\n        \n        PlanItemInstanceEntityManager planItemInstanceEntityManager = cmmnEngineConfiguration.getPlanItemInstanceEntityManager();\n        List<PlanItemInstanceEntity> planItemInstances = planItemInstanceEntityManager.findByCaseInstanceId(caseInstance.getId());\n        \n        CmmnDeploymentManager deploymentManager = cmmnEngineConfiguration.getDeploymentManager();\n        CmmnModel targetCmmnModel = deploymentManager.resolveCaseDefinition(caseInstanceChangeState.getCaseDefinitionToMigrateTo()).getCmmnModel();\n        \n        for (PlanItemInstanceEntity planItemInstanceEntity : planItemInstances) {\n            List<String> skipSentryPartInstanceForDeleteIds = new ArrayList<>();\n            if (PlanItemInstanceState.AVAILABLE.equalsIgnoreCase(planItemInstanceEntity.getState()) && \n                    sentryInstanceMap.containsKey(planItemInstanceEntity.getId())) {\n                \n                if (planItemInstanceEntity.getPlanItem() == null) {\n                    throw new FlowableException(\"Plan item could not be found for \" + planItemInstanceEntity.getElementId());\n                }\n                \n                if (planItemInstanceEntity.getPlanItem().getEntryCriteria().isEmpty()) {\n                    continue;\n                }\n                \n                for (Criterion criterion : planItemInstanceEntity.getPlanItem().getEntryCriteria()) {\n                    verifySatisfiedSentryPartsForCriterion(criterion, planItemInstanceEntity, sentryInstanceMap, \n                            skipSentryPartInstanceForDeleteIds, false, targetCmmnModel, sentryPartInstanceEntityManager);\n                }\n                \n            } else if (PlanItemInstanceState.ACTIVE.equalsIgnoreCase(planItemInstanceEntity.getState()) && \n                    sentryInstanceMap.containsKey(planItemInstanceEntity.getId())) {\n                \n                if (planItemInstanceEntity.getPlanItem() == null) {\n                    throw new FlowableException(\"Plan item could not be found for \" + planItemInstanceEntity.getElementId());\n                }\n                ","sourceCodeStart":596,"sourceCodeEnd":632,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/AbstractCmmnDynamicStateManager.java#L596-L632","documentation":"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.","triggerScenarios":"doMovePlanItemState / executeVerifySatisfiedSentryParts with an AVAILABLE plan item instance whose planItem reference is null (model lookup failed for the elementId) while sentry parts were satisfied.","commonSituations":"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.","solutions":["Redeploy the case definition containing the referenced elementId so the model can be resolved","Migrate the case instance to a definition containing the element before doing dynamic state changes","Check the case instance's case definition id vs the deployed model for version mismatch","Clear/repair the inconsistent plan item instance rows for the case instance"],"exampleFix":"// before\ncmmnRuntimeService.changePlanItemState(caseInstanceId, oldChangeState); // targets stale definition\n// after\ncmmnRuntimeService.setCaseInstanceCaseDefinition(caseInstanceId, newCaseDefinitionId); // or migrate first\ncmmnRuntimeService.changePlanItemState(caseInstanceId, changeState);","handlingStrategy":"try-catch","validationCode":"if (planItemInstanceEntity.getPlanItem() == null) {\n    throw new IllegalStateException(\"Plan item model unresolved for element \" + planItemInstanceEntity.getElementId());\n}","typeGuard":"boolean hasResolvedPlanItem(PlanItemInstance pi) {\n    return pi instanceof PlanItemInstanceEntity e && e.getPlanItem() != null;\n}","tryCatchPattern":"try {\n    cmmnRuntimeService.changePlanItemState(caseInstanceId, changeState);\n} catch (FlowableException e) {\n    if (e.getMessage().startsWith(\"Plan item could not be found\")) {\n        // migrate case instance to a definition containing the element, then retry\n    } else {\n        throw e;\n    }\n}","preventionTips":["Migrate case instances after redeploying changed case definitions","Keep element ids stable across case definition versions","Validate planItem references on case instances before dynamic state operations"],"tags":["cmmn","dynamic-state","sentry","internal"],"backgroundTag":"internal-invariant-violation","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}