flowable/flowable-engine · error · org.flowable.common.engine.api.FlowableIllegalArgumentException

Cannot combine taskIds(Collection) with withoutTaskId() in…

Error message

Cannot combine taskIds(Collection) with withoutTaskId() in the same query

What it means

InternalVariableInstanceQueryImpl.taskIds(Collection<String>) throws FlowableIllegalArgumentException when withoutTaskId was already set on the same query. 'Match these specific tasks' and 'match variables with no task' are mutually exclusive filters, so the builder rejects combining them.

Solutions

  1. Use either taskIds(...) or withoutTaskId(), never both on one query
  2. Split into two queries if both result sets are needed
  3. Refactor query construction so the filters are exclusive branches

Example fix

// before
query.withoutTaskId();
query.taskIds(ids); // throws
// after
if (ids != null && !ids.isEmpty()) {
    query.taskIds(ids);
} else {
    query.withoutTaskId();
}
Defensive patterns

Strategy: validation

Validate before calling

boolean conflict = (taskIds != null && !taskIds.isEmpty()) && useWithoutTaskId; if (conflict) throw new IllegalStateException("taskIds and withoutTaskId are mutually exclusive");

Try / catch

try { buildTaskQuery(taskIds, withoutTaskId); } catch (FlowableIllegalArgumentException e) { throw new QueryConfigurationException(e.getMessage(), e); }

Prevention

When it happens

Trigger: Calling taskIds(collection) on a query where withoutTaskId() was already called (or vice versa) on the same builder instance.

Common situations: Shared/mutated query objects across code paths; conditional filter assembly where both branches fired; copy-paste filter blocks.

Related errors


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

Appendix: source

Thrown at modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/InternalVariableInstanceQueryImpl.java:86

            throw new FlowableIllegalArgumentException("taskId is empty");
        }

        if (withoutTaskId) {
            throw new FlowableIllegalArgumentException("Cannot combine taskId(String) with withoutTaskId() in the same query");
        }

        this.taskId = taskId;
        return this;
    }

    @Override
    public InternalVariableInstanceQuery taskIds(Collection<String> taskIds) {
        if (taskIds == null || taskIds.isEmpty()) {
            throw new FlowableIllegalArgumentException("taskIds is null or empty");
        }

        if (withoutTaskId) {
            throw new FlowableIllegalArgumentException("Cannot combine taskIds(Collection) with withoutTaskId() in the same query");
        }
        this.taskIds = taskIds;
        return this;
    }

    @Override
    public InternalVariableInstanceQuery processInstanceId(String processInstanceId) {
        if (StringUtils.isEmpty(processInstanceId)) {
            throw new FlowableIllegalArgumentException("processInstanceId is empty");
        }
        this.processInstanceId = processInstanceId;
        return this;
    }

    @Override
    public InternalVariableInstanceQuery executionId(String executionId) {
        if (StringUtils.isEmpty(executionId)) {
            throw new FlowableIllegalArgumentException("executionId is empty");

View on GitHub (pinned to d6d39ce1c6)