flowable/flowable-engine · error · FlowableIllegalArgumentException

rootScopeIds is null or empty

Error message

rootScopeIds is null or empty

What it means

HistoricProcessInstanceQuery.processInstanceRootScopeIds(Set<String>) requires a non-null, non-empty set of root scope ids. Flowable throws FlowableIllegalArgumentException when rootScopeIds is null or empty because the resulting SQL IN filter would be undefined. Validation happens eagerly when building the query.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/HistoricProcessInstanceQueryImpl.java:378

            this.businessStatusLikeIgnoreCase = businessStatusLikeIgnoreCase;
        }
        return this;
    }

    @Override
    public HistoricProcessInstanceQuery processInstanceRootScopeId(String rootScopeId) {
        if (inOrStatement) {
            this.currentOrQueryObject.rootScopeId = rootScopeId;
        } else {
            this.rootScopeId = rootScopeId;
        }
        return this;
    }

    @Override
    public HistoricProcessInstanceQuery processInstanceRootScopeIds(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 HistoricProcessInstanceQuery processInstanceParentScopeId(String parentId) {
        if (inOrStatement) {
            this.currentOrQueryObject.parentScopeId = parentId;
        } else {
            this.parentScopeId = parentId;
        }
        return this;
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Ensure the set contains at least one root scope id before calling
  2. Guard with a null/isEmpty check and skip the criterion or use a different query path when absent
  3. Return an empty result early if no root scope ids are applicable
  4. Verify the id source (parent instance lookup) actually resolves values

Example fix

// before
query.processInstanceRootScopeIds(rootScopeIds); // throws when null or empty
// after
if (rootScopeIds != null && !rootScopeIds.isEmpty()) {
    query.processInstanceRootScopeIds(rootScopeIds);
}
Defensive patterns

Strategy: validation

Validate before calling

if (rootScopeIds == null || rootScopeIds.isEmpty()) {
    throw new IllegalArgumentException("rootScopeIds must be non-null and non-empty");
}
query.processInstanceRootScopeIds(rootScopeIds);

Type guard

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

Try / catch

try {
    query.processInstanceRootScopeIds(rootScopeIds);
} catch (FlowableIllegalArgumentException e) {
    log.warn("Skipping root scope filter: {}", e.getMessage());
    // continue with query minus this criterion
}

Prevention

When it happens

Trigger: Calling processInstanceRootScopeIds(rootScopeIds) with a null set or an empty set (new HashSet<>(), or a collection emptied by prior filtering).

Common situations: Hierarchical process-instance queries where the parent/root scope ids come from an optional API parameter or a lookup that returned nothing; copy-paste from processInstanceIds calls without guarding null/empty.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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