flowable/flowable-engine · error · FlowableIllegalArgumentException

None of the given process instance ids can be null

Error message

None of the given process instance ids can be null

What it means

HistoricTaskInstanceQueryImpl.processInstanceIdIn(Collection<String>) iterates the collection and throws FlowableIllegalArgumentException('None of the given process instance ids can be null') if any individual element is null, since a null id inside the IN clause is invalid. It validates each element after checking the list itself for null and emptiness.

Solutions

  1. Filter out nulls before calling: ids.removeIf(Objects::isNull) or stream().filter(Objects::nonNull).
  2. Fix the producer so missing ids are omitted rather than added as null.
  3. Optionally re-check after filtering that the list is still non-empty before applying the predicate.

Example fix

// before
query.processInstanceIdIn(rawIds); // contains null -> exception

// after
List<String> ids = rawIds.stream().filter(Objects::nonNull).collect(Collectors.toList());
if (!ids.isEmpty()) {
    query.processInstanceIdIn(ids);
}
Defensive patterns

Strategy: validation

Validate before calling

List<String> ids = rawIds == null ? Collections.emptyList() : rawIds.stream().filter(Objects::nonNull).collect(Collectors.toList());

Type guard

boolean hasNoNulls(Collection<String> c) { return c != null && c.stream().allMatch(Objects::nonNull); }

Prevention

When it happens

Trigger: Passing a Collection<String> that contains null elements (e.g. a List built with null placeholders, a map-values view containing nulls) to processInstanceIdIn.

Common situations: Ids gathered from optional lookups where missing values were stored as null; deserialized JSON arrays containing nulls; lists pre-allocated to a fixed size with unfilled slots.

Related errors


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

Appendix: source

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

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

    @Override
    public HistoricTaskInstanceQueryImpl processInstanceIdIn(Collection<String> processInstanceIds) {
        if (processInstanceIds == null) {
            throw new FlowableIllegalArgumentException("Process instance id list is null");
        }
        if (processInstanceIds.isEmpty()) {
            throw new FlowableIllegalArgumentException("Process instance id list is empty");
        }
        for (String processInstanceId : processInstanceIds) {
            if (processInstanceId == null) {
                throw new FlowableIllegalArgumentException("None of the given process instance ids can be null");
            }
        }

        if (inOrStatement) {
            this.currentOrQueryObject.processInstanceIds = processInstanceIds;
        } else {
            this.processInstanceIds = processInstanceIds;
        }
        return this;
    }
    
    @Override
    public HistoricTaskInstanceQueryImpl withoutProcessInstanceId() {
        if (inOrStatement) {
            currentOrQueryObject.withoutProcessInstanceId = true;
        } else {
            this.withoutProcessInstanceId = true;
        }

View on GitHub (pinned to d6d39ce1c6)