flowable/flowable-engine · error · FlowableIllegalArgumentException

rootScopeIds is null or empty

Error message

rootScopeIds is null or empty

What it means

Flowable's CaseInstanceQueryImpl throws FlowableIllegalArgumentException when caseInstanceRootScopeIds(Set<String>) is called with a null or empty set. The query API requires at least one root scope id because an empty IN-clause would produce invalid or meaningless SQL against the case instance table. Throwing early gives immediate feedback instead of a broken query at execution time.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/CaseInstanceQueryImpl.java:386

    }

    @Override
    public CaseInstanceQuery 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 CaseInstanceQuery 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 CaseInstanceQuery 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

  1. Ensure at least one root scope id is resolved before calling the method; skip the filter clause entirely when the set is empty instead of calling it
  2. Guard the call: only invoke caseInstanceRootScopeIds when ids != null && !ids.isEmpty()
  3. Check the upstream data source that produces the ids (parent case/process instance actually exists)
  4. If the intent is 'all case instances', drop the root-scope criterion rather than passing an empty set

Example fix

// before
query.caseInstanceRootScopeIds(collectRootScopeIds()); // NPE/empty -> FlowableIllegalArgumentException
// after
Set<String> rootScopeIds = collectRootScopeIds();
if (rootScopeIds != null && !rootScopeIds.isEmpty()) {
    query.caseInstanceRootScopeIds(rootScopeIds);
}
Defensive patterns

Strategy: validation

Validate before calling

if (rootScopeIds == null || rootScopeIds.isEmpty()) {
    throw new IllegalArgumentException("rootScopeIds must contain at least one id");
}
query.caseInstanceRootScopeIds(rootScopeIds);

Type guard

boolean hasRootScopeIds(Set<String> ids) {
    return ids != null && !ids.isEmpty();
}

Try / catch

try {
    query.caseInstanceRootScopeIds(rootScopeIds);
} catch (FlowableIllegalArgumentException e) {
    log.warn("Invalid root scope ids for case instance query: {}", e.getMessage());
    // rebuild query without the root-scope criterion or fail the request with 400
}

Prevention

When it happens

Trigger: Calling cmmnRuntimeService.createCaseInstanceQuery().caseInstanceRootScopeIds(null), or caseInstanceRootScopeIds(Collections.emptySet()) / a Set that was filtered down to zero elements, before executing the query.

Common situations: Building queries dynamically where root scope ids come from an upstream lookup (parent process/relation table) that returned nothing; passing an unfiltered collection variable; copying code from caseInstanceParentScopeIds and passing the wrong (empty) collection; unit tests with no seeded data.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/bdd6801c90b674bc. Report an issue: GitHub.