flowable/flowable-engine · critical · FlowableException
Could not find plan item instance for
Error message
Could not find plan item instance for
What it means
Thrown by CompleteTaskCmd when the task's subScopeId points to a plan item instance that no longer exists in the CMMN database. The task is linked to a CMMN plan item (e.g. a case user task) but the plan item row is missing, so the engine cannot complete the plan item as part of completing the task. This indicates internal data inconsistency, typically a concurrently deleted/finished case.
Solutions
- Verify the case instance and plan item instance still exist and are active before completing the task.
- Avoid manual deletes on ACT_CMMN_* tables; use the engine's CaseInstanceService/terminate APIs to end cases.
- Check for concurrent termination of the case and handle FlowableException gracefully (task no longer completable).
- If data is inconsistent, re-seed from a consistent backup or use Flowable's database consistency checks.
Defensive patterns
Strategy: try-catch
Validate before calling
if (cmmnRuntimeService.createCaseInstanceQuery().caseInstanceId(task.getScopeId()).count() == 0) {
throw new IllegalStateException("Case already terminated; task not completable");
} Try / catch
try {
cmmnTaskService.completeTask(taskId);
} catch (FlowableException e) {
if (e.getMessage() != null && e.getMessage().contains("Could not find plan item instance")) {
log.warn("Plan item for task {} vanished (case terminated concurrently?)", taskId);
// surface stale-task state to the user instead of retrying
} else {
throw e;
}
} Prevention
- Never delete or edit ACT_CMMN_* runtime tables manually.
- Terminate cases through engine APIs so dependent rows are removed consistently.
- Refresh task lists after case termination to purge stale tasks in the UI.
When it happens
Trigger: Completing a CMMN task whose subScopeId no longer resolves via planItemInstanceEntityManager.findById: the case/plan item was terminated or deleted concurrently, or the database rows were partially removed/manipulated externally.
Common situations: Race between a user completing a task and another user terminating the case; custom SQL/manual cleanup of CMMN tables; restoring a database backup for only some tables; failed cascade deletes.
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
- Could not find plan item instance for
- No plan item instance found for id
- No plan item instance found for id
- a suspended
- activatedBefore is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/3adf60bc665ad960.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/CompleteTaskCmd.java:98
throw new FlowableIllegalArgumentException("Null task id");
}
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
TaskEntity taskEntity = cmmnEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);
if (taskEntity == null) {
throw new FlowableObjectNotFoundException("Could not find task entity for id " + taskId, TaskEntity.class);
}
if (StringUtils.isNotEmpty(taskEntity.getProcessInstanceId())) {
throw new FlowableException(taskEntity + " is created by the process engine and should be completed via the process engine API");
}
String planItemInstanceId = taskEntity.getSubScopeId();
PlanItemInstanceEntity planItemInstanceEntity = null;
if (planItemInstanceId != null) {
planItemInstanceEntity = cmmnEngineConfiguration.getPlanItemInstanceEntityManager().findById(planItemInstanceId);
if (planItemInstanceEntity == null) {
throw new FlowableException("Could not find plan item instance for " + taskEntity);
}
}
if (variables != null) {
taskEntity.setVariables(variables);
}
if (variablesLocal != null) {
taskEntity.setVariablesLocal(variablesLocal);
}
if (transientVariables != null) {
taskEntity.setTransientVariables(transientVariables);
}
if (transientVariablesLocal != null) {
taskEntity.setTransientVariablesLocal(transientVariablesLocal);
}
logUserTaskCompleted(taskEntity, cmmnEngineConfiguration);
View on GitHub (pinned to d6d39ce1c6)