flowable/flowable-engine · error · FlowableIllegalArgumentException

Task id list is null

Error message

Task id list is null

What it means

HistoricTaskInstanceQueryImpl.taskIds(Collection) throws FlowableIllegalArgumentException when the taskIds collection is null. The collection feeds the query's IN clause over task IDs, which requires a concrete set of identifiers. Flowable validates this eagerly so the failure surfaces at query construction instead of at SQL execution.

Solutions

  1. Initialize the collection before use (e.g. new ArrayList<>()).
  2. Guard the call: only pass taskIds when the reference is non-null and non-empty.
  3. If the intent is 'no filtering by IDs', omit the taskIds call entirely.

Example fix

// before
query.taskIds(collectedTaskIds); // may be null
// after
if (collectedTaskIds != null && !collectedTaskIds.isEmpty()) {
    query.taskIds(collectedTaskIds);
}
Defensive patterns

Strategy: validation

Validate before calling

if (taskIds == null || taskIds.isEmpty()) {
    throw new IllegalArgumentException("taskIds requires a non-empty list");
}

Type guard

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

Try / catch

try {
    query.taskIds(ids);
} catch (FlowableIllegalArgumentException e) {
    logger.warn("Invalid task id list: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling historicTaskInstanceQuery().taskIds(null), typically when the ID collection comes from an uninitialized variable or a null-returning lookup.

Common situations: Result of a previous search/cache miss returned null; conditional code path never populated the collection; API callers passing null intending 'no filter'.

Related errors


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

Appendix: source

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

            this.cmmnDeploymentIds = cmmnDeploymentIds;
        }
        return this;
    }

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

    @Override
    public HistoricTaskInstanceQuery taskIds(Collection<String> taskIds) {
        if (taskIds == null) {
            throw new FlowableIllegalArgumentException("Task id list is null");
        }
        if (taskIds.isEmpty()) {
            throw new FlowableIllegalArgumentException("Task id list is empty");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.taskIds = taskIds;
        } else {
            this.taskIds = taskIds;
        }
        return this;
    }

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

View on GitHub (pinned to d6d39ce1c6)