flowable/flowable-engine · error · org.flowable.common.engine.api.FlowableIllegalArgumentException
Cannot use taskIds together with excludeLocalVariables
Error message
Cannot use taskIds together with excludeLocalVariables
What it means
Flowable throws this when HistoricVariableInstanceQuery.taskIds(Collection) is called after excludeLocalVariables() has been set. Task-scoped taskIds queries and the excludeLocalVariables filter are semantically incompatible, so the library rejects the combination eagerly at call time instead of producing a misleading query result. This is an argument-consistency guard in HistoricVariableInstanceQueryImpl.taskIds().
Source
Thrown at modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/HistoricVariableInstanceQueryImpl.java:157
throw new FlowableIllegalArgumentException("Cannot use taskId together with excludeLocalVariables");
}
this.taskId = taskId;
return this;
}
@Override
public HistoricVariableInstanceQueryImpl taskIds(Set<String> taskIds) {
if (taskIds == null) {
throw new FlowableIllegalArgumentException("taskIds is null");
}
if (taskIds.isEmpty()) {
throw new FlowableIllegalArgumentException("Set of taskIds is empty");
}
if (excludeTaskRelated) {
throw new FlowableIllegalArgumentException("Cannot use taskIds together with excludeTaskVariables");
}
if (excludeLocalVariables) {
throw new FlowableIllegalArgumentException("Cannot use taskIds together with excludeLocalVariables");
}
this.taskIds = taskIds;
return this;
}
@Override
public HistoricVariableInstanceQuery excludeTaskVariables() {
if (taskId != null) {
throw new FlowableIllegalArgumentException("Cannot use taskId together with excludeTaskVariables");
}
if (taskIds != null) {
throw new FlowableIllegalArgumentException("Cannot use taskIds together with excludeTaskVariables");
}
excludeTaskRelated = true;
return this;
}
@OverrideView on GitHub (pinned to d6d39ce1c6)
Solutions
- Remove the excludeLocalVariables() call from the query when filtering by taskIds.
- Reorder the chain is not enough — the check fires on state, so actually drop one of the two conflicting settings.
- If non-local variables are needed per task set, query without excludeLocalVariables and filter results in application code.
- Check for conditionally-set flags (e.g. booleans from request parameters) that enable excludeLocalVariables unintentionally.
Example fix
// before
historyService.createHistoricVariableInstanceQuery()
.taskIds(taskIds)
.excludeLocalVariables()
.list();
// after
historyService.createHistoricVariableInstanceQuery()
.taskIds(taskIds)
.list(); Defensive patterns
Strategy: validation
Validate before calling
if (excludeLocalVariablesRequested) {
throw new IllegalStateException("taskIds() cannot be combined with excludeLocalVariables()");
}
// otherwise build the query
query.taskIds(taskIds); Prevention
- Keep mutually exclusive query flags in separate builder branches.
- Never unconditionally append exclusion flags in shared query-builder helpers.
- Unit-test each combination of scoping + exclusion flags you use.
When it happens
Trigger: Calling setTaskIds(taskIds) (taskIds setter, line ~157) while the excludeLocalVariables flag is already true — i.e. excludeLocalVariables() was invoked earlier in the fluent chain, or was called before taskIds() in a different order.
Common situations: Building a fluent query where both filters are applied conditionally: a developer wants 'all non-local variables for these tasks' and chains .excludeLocalVariables().taskIds(ids). Also happens when refactoring code from taskId-based to taskIds-based queries without removing the exclusion flag.
Related errors
- version must be positive
- variableName is null
- caseInstanceId is null
- The case definition id is mandatory, but '' has been provide
- after time is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0344189bdc1abe99.
Report an issue: GitHub.