flowable/flowable-engine · error · FlowableIllegalArgumentException
planItemInstanceId is null
Error message
planItemInstanceId is null
What it means
HasPlanItemInstanceVariableCmd.execute throws FlowableIllegalArgumentException when planItemInstanceId is null. The command requires both a plan item instance id and a variable name; without the id it cannot locate the plan item instance, so it fails fast before any database access.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/HasPlanItemInstanceVariableCmd.java:39
import org.flowable.common.engine.impl.interceptor.CommandContext;
/**
* @author Christopher Welsch
*/
public class HasPlanItemInstanceVariableCmd implements Command<Boolean> {
protected String planItemInstanceId;
protected String variableName;
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
- Ensure the plan item instance id is captured from a valid PlanItemInstance before calling
- Guard the call with a null check on the id
- If deriving the id from a query, handle the null singleResult() case first
Example fix
// before
boolean has = cmmnRuntimeService.hasPlanItemVariable(planItemInstanceId, "flag");
// after
if (planItemInstanceId != null) {
boolean has = cmmnRuntimeService.hasPlanItemVariable(planItemInstanceId, "flag");
} Defensive patterns
Strategy: validation
Validate before calling
if (planItemInstanceId == null) {
throw new IllegalArgumentException("planItemInstanceId is required");
} Type guard
boolean hasPlanItemInstanceId(String id) {
return id != null && !id.isEmpty();
} Try / catch
try {
return cmmnRuntimeService.hasPlanItemVariable(planItemInstanceId, variableName);
} catch (FlowableIllegalArgumentException e) {
log.warn("Invalid hasPlanItemVariable args: {}", e.getMessage());
return false;
} Prevention
- Capture plan item ids only from live PlanItemInstance objects inside listeners
- Null-check ids from upstream lookups
- Use a facade that validates arguments before delegating to the runtime service
When it happens
Trigger: Calling cmmnRuntimeService.hasPlanItemVariable(null, variableName) or the local variant, or constructing the command directly with a null id.
Common situations: Plan item id obtained from a listener/stage context that was null (e.g. evaluated outside an active plan item), an uninitialized variable in custom delegation code, or a lookup that returned no result upstream.
Related errors
- Plan item instance id is null
- Could not resolve case instance id
- Can only trigger a plan item that is in the ACTIVE state
- Case instance id is null
- Cannot find plan item instance for id ${planItemInstanceId}
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/3334b7795e9d4470.
Report an issue: GitHub.