flowable/flowable-engine · error · FlowableIllegalArgumentException
rootScopeIds is null or empty
Error message
rootScopeIds is null or empty
What it means
caseInstanceRootScopeIds(Set<String>) throws 'rootScopeIds is null or empty' when the set is null or has no elements. Unlike most setters that only reject null, this one also rejects an empty set, so callers must supply at least one root scope id.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricCaseInstanceQueryImpl.java:422
}
@Override
public HistoricCaseInstanceQueryImpl caseInstanceRootScopeId(String rootScopeId) {
if (rootScopeId == null) {
throw new FlowableIllegalArgumentException("rootScopeId is null");
}
if (inOrStatement) {
this.currentOrQueryObject.rootScopeId = rootScopeId;
} else {
this.rootScopeId = rootScopeId;
}
return this;
}
@Override
public HistoricCaseInstanceQuery caseInstanceRootScopeIds(Set<String> rootScopeIds) {
if (rootScopeIds == null || rootScopeIds.isEmpty()) {
throw new FlowableIllegalArgumentException("rootScopeIds is null or empty");
}
if (inOrStatement) {
this.currentOrQueryObject.rootScopeIds = rootScopeIds;
} else {
this.rootScopeIds = rootScopeIds;
}
return this;
}
@Override
public HistoricCaseInstanceQueryImpl caseInstanceParentScopeId(String parentScopeId) {
if (parentScopeId == null) {
throw new FlowableIllegalArgumentException("parentScopeId is null");
}
if (inOrStatement) {
this.currentOrQueryObject.parentScopeId = parentScopeId;
} else {
this.parentScopeId = parentScopeId;View on GitHub (pinned to d6d39ce1c6)
Solutions
- Ensure the set contains at least one id before calling.
- Skip the setter entirely (no root-scope filter) when the set is empty.
- Catch FlowableIllegalArgumentException and return a 'select at least one scope' validation message.
Example fix
// before
query.caseInstanceRootScopeIds(selectedRootIds); // may be null/empty
// after
if (selectedRootIds != null && !selectedRootIds.isEmpty()) {
query.caseInstanceRootScopeIds(selectedRootIds);
} Defensive patterns
Strategy: validation
Validate before calling
if (rootScopeIds == null || rootScopeIds.isEmpty()) { throw new IllegalArgumentException("rootScopeIds must contain at least one id"); }
historicCaseInstanceQuery.caseInstanceRootScopeIds(rootScopeIds); Type guard
boolean hasRootScopeIds(Set<String> ids) { return ids != null && !ids.isEmpty(); } Try / catch
try {
query.caseInstanceRootScopeIds(rootScopeIds);
} catch (FlowableIllegalArgumentException e) {
throw new BadRequestException("At least one root scope id is required", e);
} Prevention
- Remember this setter rejects empty sets, unlike most others
- Skip the filter entirely when no root scopes are selected
- Guard against empty results from stream/filter operations
- Return a clear validation message when a selection is required
When it happens
Trigger: Calling caseInstanceRootScopeIds(null) or caseInstanceRootScopeIds(new HashSet<>()) / an empty collection produced by filtering.
Common situations: Dynamic filter builders that collect selected root scopes from UI selections where nothing was selected; stream filters that removed all entries.
Related errors
- Case definition version is null
- Case instance id is null
- Case instance ids is null
- Business key is null
- rootScopeId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/5971013f75aec90f.
Report an issue: GitHub.