flowable/flowable-engine · error · FlowableException
Cannot find plan item with definition id '<planItemDefinitio
Error message
Cannot find plan item with definition id '<planItemDefinitionId>' in case definition with id '<caseDefinitionId>'
What it means
Flowable throws this FlowableException when a dynamic CMMN case modification cannot resolve a plan item in the loaded CMMN model by plan item definition id. resolvePlanItemFromCmmnModelWithDefinitionId looks up the element via CmmnModel.findPlanItemByPlanItemDefinitionId and aborts when no matching plan item exists in the target case definition.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/AbstractCmmnDynamicStateManager.java:112
/**
* @author Tijs Rademakers
* @author Valentin Zickner
*/
public abstract class AbstractCmmnDynamicStateManager {
protected final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
protected CmmnEngineConfiguration cmmnEngineConfiguration;
public AbstractCmmnDynamicStateManager(CmmnEngineConfiguration cmmnEngineConfiguration) {
this.cmmnEngineConfiguration = cmmnEngineConfiguration;
}
protected PlanItem resolvePlanItemFromCmmnModelWithDefinitionId(String planItemDefinitionId, String caseDefinitionId) {
CmmnModel cmmnModel = CaseDefinitionUtil.getCmmnModel(caseDefinitionId);
PlanItem planItem = cmmnModel.findPlanItemByPlanItemDefinitionId(planItemDefinitionId);
if (planItem == null) {
throw new FlowableException("Cannot find plan item with definition id '" + planItemDefinitionId + "' in case definition with id '" + caseDefinitionId + "'");
}
return planItem;
}
protected PlanItem resolvePlanItemFromCmmnModel(CmmnModel cmmnModel, String planItemId, String caseDefinitionId) {
PlanItem planItem = cmmnModel.findPlanItem(planItemId);
if (planItem == null) {
throw new FlowableException("Cannot find plan item '" + planItemId + "' in case definition with id '" + caseDefinitionId + "'");
}
return planItem;
}
protected void doMovePlanItemState(CaseInstanceChangeState caseInstanceChangeState, String originalCaseDefinitionId, CommandContext commandContext) {
CaseInstanceEntityManager caseInstanceEntityManager = cmmnEngineConfiguration.getCaseInstanceEntityManager();
CaseInstanceEntity caseInstance = caseInstanceEntityManager.findById(caseInstanceChangeState.getCaseInstanceId());
Map<String, List<PlanItemInstanceEntity>> currentPlanItemInstances = retrievePlanItemInstances(caseInstanceChangeState.getCaseInstanceId());
caseInstanceChangeState.setCurrentPlanItemInstances(currentPlanItemInstances);View on GitHub (pinned to d6d39ce1c6)
Solutions
- Verify planItemDefinitionId exists in the deployed case's CMMN XML (<planItem> whose planItemDefinition has that id)
- Confirm the caseDefinitionId points to the case definition version that actually contains the plan item (check ACT_CMMN_CASEDEF / repository)
- Re-fetch the case definition and list its plan items (e.g. via the CmmnModel) to pick a valid id
- If the case model changed, update the change-state/migration request to use the new definition ids
Example fix
// before
changeStateBuilder.planItem("nonexistentStepId", "caseDef-1");
// after
CmmnModel model = CaseDefinitionUtil.getCmmnModel("caseDef-1");
if (model.findPlanItemByPlanItemDefinitionId("stepId") != null) {
changeStateBuilder.planItem("stepId", "caseDef-1");
} Defensive patterns
Strategy: validation
Validate before calling
CmmnModel model = CaseDefinitionUtil.getCmmnModel(caseDefinitionId);
if (model.findPlanItemByPlanItemDefinitionId(planItemDefinitionId) == null) {
throw new IllegalArgumentException("Unknown planItemDefinitionId: " + planItemDefinitionId);
} Type guard
boolean planItemExists = cmmnModel.findPlanItemByPlanItemDefinitionId(planItemDefinitionId) != null;
Try / catch
try {
changeStateBuilder.planItem(planItemDefinitionId, caseDefinitionId);
} catch (FlowableException e) {
if (e.getMessage().startsWith("Cannot find plan item")) {
// refresh case definition ids and retry with corrected ids
}
} Prevention
- Extract plan item definition ids from the deployed case definition version, not from older deployments
- Revalidate ids after redeploying changed CMMN models
- Keep case migration requests in sync with renamed/removed plan items
- Log the available plan item definition ids when resolution fails to speed up diagnosis
When it happens
Trigger: Calling case modification/change-state APIs such as planItem(...) on CaseChangeStateRequest/builders with a planItemDefinitionId that does not exist in the case definition identified by caseDefinitionId — e.g. after redeploying a changed case model, using an id from a different case, or a typo in the definition id.
Common situations: Case migration between case definition versions where a plan item was renamed or removed; runtime operations referencing a stale case definition id after a new deployment; programmatically generated definition ids not matching the deployed CMMN XML.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Can only trigger a plan item that is in the ACTIVE state
- Plan item instance id is null
- Cannot find plan item instance for id ${planItemInstanceId}
- No move plan item instance or (activate) plan item definitio
- Case instance id is required
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/60a9e6885e40bcef.
Report an issue: GitHub.