flowable/flowable-engine · error · FlowableIllegalArgumentException

Process category list is empty

Error message

Process category list is empty

What it means

HistoricTaskInstanceQueryImpl.processCategoryIn(Collection<String>) throws FlowableIllegalArgumentException('Process category list is empty') when given a non-null but zero-size collection, because an IN predicate with no values is invalid. At least one category must be supplied.

Solutions

  1. Short-circuit: if the category list is empty, return no results (or drop the filter if an empty selection means 'no restriction').
  2. Only call processCategoryIn when the list has at least one element.
  3. Ensure upstream filtering doesn't silently remove all categories.

Example fix

// before
query.processCategoryIn(selectedCategories); // empty -> exception

// after
if (selectedCategories.isEmpty()) {
    return Collections.emptyList();
}
query.processCategoryIn(selectedCategories);
Defensive patterns

Strategy: validation

Validate before calling

if (categories == null || categories.isEmpty()) {
    return Collections.emptyList(); // or drop the filter if empty means 'no restriction'
}

Type guard

boolean isUsableCategoryList(Collection<String> c) { return c != null && !c.isEmpty(); }

Prevention

When it happens

Trigger: Calling processCategoryIn(Collections.emptyList()) or a list that was emptied by prior filtering just before the query is built.

Common situations: UI filters where the user deselects all categories and the empty selection is passed through; downstream filtering (e.g. permission-based) removing every category.

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/09c1acc0139c9d1f. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/HistoricTaskInstanceQueryImpl.java:622

    }

    @Override
    public HistoricTaskInstanceQuery processDefinitionNameLike(String processDefinitionNameLike) {
        if (inOrStatement) {
            this.currentOrQueryObject.processDefinitionNameLike = processDefinitionNameLike;
        } else {
            this.processDefinitionNameLike = processDefinitionNameLike;
        }
        return this;
    }

    @Override
    public HistoricTaskInstanceQuery processCategoryIn(Collection<String> processCategoryInList) {
        if (processCategoryInList == null) {
            throw new FlowableIllegalArgumentException("Process category list is null");
        }
        if (processCategoryInList.isEmpty()) {
            throw new FlowableIllegalArgumentException("Process category list is empty");
        }
        for (String processCategory : processCategoryInList) {
            if (processCategory == null) {
                throw new FlowableIllegalArgumentException("None of the given process categories can be null");
            }
        }

        if (inOrStatement) {
            currentOrQueryObject.processCategoryInList = processCategoryInList;
        } else {
            this.processCategoryInList = processCategoryInList;
        }
        return this;
    }

    @Override
    public HistoricTaskInstanceQuery processCategoryNotIn(Collection<String> processCategoryNotInList) {
        if (processCategoryNotInList == null) {

View on GitHub (pinned to d6d39ce1c6)