flowable/flowable-engine · error · FlowableObjectNotFoundException
Cannot find plan item instance for id ${planItemInstanceId}
Error message
Cannot find plan item instance for id ${planItemInstanceId} What it means
FlowableObjectNotFoundException thrown in AbstractNeedsPlanItemInstanceCmd.execute when PlanItemInstanceEntityManager.findById returns null for the supplied id. The id was non-null but no plan item instance exists in the runtime tables (ACT_CMMN_RU_PLAN_ITEM_INST). Common when the plan item already completed or the id is from history.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/AbstractNeedsPlanItemInstanceCmd.java:70
this.planItemInstanceId = planItemInstanceId;
this.variables = variables;
this.formVariables = formVariables;
this.formOutcome = formOutcome;
this.formInfo = formInfo;
this.localVariables = localVariables;
this.transientVariables = transientVariables;
}
@Override
public Void execute(CommandContext commandContext) {
if (planItemInstanceId == null) {
throw new FlowableIllegalArgumentException("Plan item instance id is null");
}
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
PlanItemInstanceEntity planItemInstanceEntity = cmmnEngineConfiguration.getPlanItemInstanceEntityManager().findById(planItemInstanceId);
if (planItemInstanceEntity == null) {
throw new FlowableObjectNotFoundException("Cannot find plan item instance for id " + planItemInstanceId, PlanItemInstanceEntity.class);
}
if (formInfo != null) {
FormService formService = CommandContextUtil.getFormService(commandContext);
if (formService == null) {
throw new FlowableIllegalStateException("Form engine is not initialized");
}
Map<String, Object> variablesFromFormSubmission = formService.getVariablesFromFormSubmission(planItemInstanceEntity.getPlanItemDefinitionId(),
planItemInstanceEntity.getPlanItemDefinitionType(), planItemInstanceEntity.getCaseInstanceId(), planItemInstanceEntity.getCaseDefinitionId(),
ScopeTypes.CMMN, formInfo, formVariables, formOutcome);
FormFieldHandler formFieldHandler = cmmnEngineConfiguration.getFormFieldHandler();
formFieldHandler.handleFormFieldsOnSubmit(formInfo, null, null, planItemInstanceEntity.getCaseInstanceId(), ScopeTypes.CMMN, variablesFromFormSubmission,
planItemInstanceEntity.getTenantId());
planItemInstanceEntity.setVariables(variablesFromFormSubmission);
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Query cmmnRuntimeService.createPlanItemInstanceQuery().planItemInstanceId(id).singleResult() first and check state is active before completing
- Handle double submissions idempotently in your client (disable buttons/track submitted ids)
- Use cmmnHistoryService for data about completed plan items
- Verify you are querying the correct engine/database/tenant
Example fix
// before
cmmnTaskService.completePlanItemPlanForm(planItemInstanceId, caseInstanceId, formInfo, variables, null);
// after
PlanItemInstance pii = cmmnRuntimeService.createPlanItemInstanceQuery().planItemInstanceId(planItemInstanceId).singleResult();
if (pii == null || !PlanItemInstanceState.ACTIVE.equals(pii.getState())) {
throw new IllegalStateException("Plan item " + planItemInstanceId + " is not active");
}
cmmnTaskService.completePlanItemPlanForm(planItemInstanceId, caseInstanceId, formInfo, variables, null); Defensive patterns
Strategy: validation
Validate before calling
PlanItemInstance pii = cmmnRuntimeService.createPlanItemInstanceQuery().planItemInstanceId(planItemInstanceId).singleResult();
if (pii == null) throw new IllegalStateException("Plan item instance " + planItemInstanceId + " not found or already completed"); Try / catch
try { cmmnTaskService.completePlanItemPlanForm(...); }
catch (FlowableObjectNotFoundException e) { log.info("Plan item {} already completed/removed", planItemInstanceId); } Prevention
- Check plan item state is ACTIVE before completing
- Make form submissions idempotent to survive double clicks
- Use cmmnHistoryService for completed plan item data
- Watch for concurrent case termination invalidating plan item ids
When it happens
Trigger: Completing/triggering a plan item that already reached a terminal state (completed/terminated/exited) and whose runtime row was removed; using a historic plan item instance id; wrong database or tenant; id typo.
Common situations: Double-submission of a form (second call after plan item completed); case instance terminated concurrently by another user; using planItemInstanceId from a completed case's history endpoint.
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
- Cannot find plan item instance with id
- plan item instance ${planItemInstanceId} doesn't exist
- Can only trigger a plan item that is in the ACTIVE state
- Cannot find case instance for id ${caseInstanceId}
- Plan item instance id is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/993cdd2b83eb56d1.
Report an issue: GitHub.