flowable/flowable-engine · error · FlowableObjectNotFoundException
plan item instance ${planItemInstanceId} doesn't exist
Error message
plan item instance ${planItemInstanceId} doesn't exist What it means
HasPlanItemInstanceVariableCmd.execute throws FlowableObjectNotFoundException when the given planItemInstanceId does not match any plan item instance in the runtime tables. The ids were valid non-null values, but findById returned null, so the engine reports the plan item instance as nonexistent rather than returning false for the variable check.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/HasPlanItemInstanceVariableCmd.java:48
public HasPlanItemInstanceVariableCmd(String caseInstanceId, String variableName) {
this.planItemInstanceId = caseInstanceId;
this.variableName = variableName;
}
@Override
public Boolean execute(CommandContext commandContext) {
if (planItemInstanceId == null) {
throw new FlowableIllegalArgumentException("planItemInstanceId is null");
}
if (variableName == null) {
throw new FlowableIllegalArgumentException("variableName is null");
}
PlanItemInstanceEntity planItemInstance = CommandContextUtil.getPlanItemInstanceEntityManager(commandContext).findById(planItemInstanceId);
if (planItemInstance == null) {
throw new FlowableObjectNotFoundException("plan item instance " + planItemInstanceId + " doesn't exist", PlanItemInstance.class);
}
return planItemInstance.hasVariableLocal(variableName);
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Look up the plan item first via a PlanItemInstanceQuery and handle absence
- If the plan item may have completed, query cmmnHistoryService plan item instance data instead
- Validate the id source and database/schema targeting
Example fix
// before
boolean has = cmmnRuntimeService.hasPlanItemVariable(piId, "flag");
// after
PlanItemInstance pii = cmmnRuntimeService.createPlanItemInstanceQuery()
.planItemInstanceId(piId).singleResult();
boolean has = pii != null && cmmnRuntimeService.hasPlanItemVariable(piId, "flag"); Defensive patterns
Strategy: try-catch
Validate before calling
PlanItemInstance pii = cmmnRuntimeService.createPlanItemInstanceQuery()
.planItemInstanceId(planItemInstanceId).singleResult();
if (pii == null) {
// plan item absent; use history if needed
} Type guard
boolean planItemExists(CmmnRuntimeService rs, String id) {
return id != null && rs.createPlanItemInstanceQuery().planItemInstanceId(id).singleResult() != null;
} Try / catch
try {
return cmmnRuntimeService.hasPlanItemVariable(piId, variableName);
} catch (FlowableObjectNotFoundException e) {
log.warn("Plan item instance {} not found", piId);
return false;
} Prevention
- Don't cache plan item ids across state transitions; re-query
- Use history service for terminated/completed plan items
- Validate ids against the correct engine/database environment
When it happens
Trigger: Calling hasPlanItemVariable with an id of a plan item that already completed/terminated, a malformed id, or an id from a different case/engine instance.
Common situations: Checking variables after the stage/plan item moved to a terminal state, stale ids cached in application state, tests with hard-coded ids, pointing at a different database environment.
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 for id ${planItemInstanceId}
- Cannot find plan item instance with id
- 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/f46d1e759c9938fe.
Report an issue: GitHub.