flowable/flowable-engine · error · FlowableIllegalArgumentException
Stage instance id is null
Error message
Stage instance id is null
What it means
Flowable's PlanItemInstanceQuery.stageInstanceId() throws FlowableIllegalArgumentException when stageInstanceId is null. This filter narrows plan item instances to those inside a specific stage; the setter validates the argument eagerly so malformed queries never reach the database.
Solutions
- Pass a valid stage instance id (resolve it via PlanItemRuntimeService for the stage plan item)
- Only call stageInstanceId(id) when the id is non-null; at root level, omit the filter
- Null-check the PlanItemInstance representing the stage before using its getId()
Example fix
// before
query.stageInstanceId(stage.getId()); // stage may be null
// after
if (stage != null) {
query.stageInstanceId(stage.getId());
} Defensive patterns
Strategy: validation
Validate before calling
if (stageInstanceId != null && !stageInstanceId.isBlank()) {
query.stageInstanceId(stageInstanceId);
} Type guard
boolean isPresent(String id) { return id != null && !id.isBlank(); } Try / catch
try {
query.stageInstanceId(stageInstanceId);
} catch (FlowableIllegalArgumentException e) {
log.warn("Stage filter skipped: {}", e.getMessage());
} Prevention
- Null-check the stage PlanItemInstance before using its id as a filter
- Handle the 'no active stage' case explicitly in case navigation code
- Nullify UI selections into 'no filter' rather than null ids reaching the query
When it happens
Trigger: Calling stageInstanceId(null), e.g. when the stage instance id comes from a plan item lookup that returned null, an unset variable, or an absent request parameter.
Common situations: Navigating a case hierarchy where the code assumes a parent stage exists; querying at case root level where no stage is active; UI code passing a cleared selection field.
Related errors
- activatedBefore is null
- assignee is null
- availableAfter is null
- availableBefore is null
- before time is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/e720008aeddaa17d.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceQueryImpl.java:180
if (caseInstanceIds == null) {
throw new FlowableIllegalArgumentException("Set of case instance ids is null");
}
if (caseInstanceIds.isEmpty()) {
throw new FlowableIllegalArgumentException("Set of case instance ids is empty");
}
if (inOrStatement) {
this.currentOrQueryObject.caseInstanceIds = caseInstanceIds;
} else {
this.caseInstanceIds = caseInstanceIds;
}
return this;
}
@Override
public PlanItemInstanceQuery stageInstanceId(String stageInstanceId) {
if (stageInstanceId == null) {
throw new FlowableIllegalArgumentException("Stage instance id is null");
}
if (inOrStatement) {
this.currentOrQueryObject.stageInstanceId = stageInstanceId;
} else {
this.stageInstanceId = stageInstanceId;
}
return this;
}
@Override
public PlanItemInstanceQuery planItemInstanceId(String planItemInstanceId) {
if (planItemInstanceId == null) {
throw new FlowableIllegalArgumentException("Plan Item instance id is null");
}
if (inOrStatement) {
this.currentOrQueryObject.planItemInstanceId = planItemInstanceId;
} else {
this.planItemInstanceId = planItemInstanceId;View on GitHub (pinned to d6d39ce1c6)