flowable/flowable-engine · error · FlowableIllegalArgumentException
Set of taskIds is empty
Error message
Set of taskIds is empty
What it means
GetTasksLocalVariablesCmd throws FlowableIllegalArgumentException("Set of taskIds is empty") when the supplied task id collection is non-null but has no elements. An empty IN-clause query is meaningless and would either fail in SQL or return misleading results, so the engine rejects it eagerly.
Solutions
- Check !taskIds.isEmpty() before calling the batch API and skip the call when empty.
- Return an empty variable map/result directly for an empty id set instead of querying.
- Fix the filtering logic that unexpectedly reduces the id set to zero if a non-empty set was expected.
- Catch FlowableIllegalArgumentException as a client-side validation failure.
Example fix
// before
List<VariableInstance> vars = taskService.getTasksLocalVariables(taskIds);
// after
Map<String, List<VariableInstance>> varsByTask = taskIds.isEmpty()
? Collections.emptyMap()
: groupVariables(taskService.getTasksLocalVariables(taskIds)); Defensive patterns
Strategy: validation
Validate before calling
if (taskIds == null || taskIds.isEmpty()) {
return Collections.emptyMap(); // skip the query entirely
} Type guard
boolean isNonEmpty(Collection<String> ids) { return ids != null && !ids.isEmpty(); } Try / catch
try {
return taskService.getTasksLocalVariables(taskIds);
} catch (FlowableIllegalArgumentException e) {
return Collections.emptyList();
} Prevention
- Short-circuit batch queries on empty inputs — return empty results instead
- Check upstream filters that can legitimately reduce the id set to zero
- Wrap batch APIs in helpers that normalize null/empty inputs
When it happens
Trigger: taskService.getTasksLocalVariables(Collections.emptySet()) or passing an id collection that was filtered down to zero items (e.g. all tasks already completed) before the batch variable fetch.
Common situations: Bulk UI pages loading variables for a task list that happens to be empty; filtering by criteria that matched nothing; passing a freshly created but unpopulated collection.
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
- at least one of userId or groups must be provided
- callbackIds is null or empty
- Could not find a deployment with id
- Could not find an app definition with id
- Empty appsDefinitionIds
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/61cdf08891881d5e.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetTasksLocalVariablesCmd.java:47
/**
* @author Daisuke Yoshimoto
*/
public class GetTasksLocalVariablesCmd implements Command<List<VariableInstance>>, Serializable {
private static final long serialVersionUID = 1L;
protected Set<String> taskIds;
public GetTasksLocalVariablesCmd(Set<String> taskIds) {
this.taskIds = taskIds;
}
@Override
public List<VariableInstance> execute(CommandContext commandContext) {
if (taskIds == null) {
throw new FlowableIllegalArgumentException("taskIds is null");
}
if (taskIds.isEmpty()) {
throw new FlowableIllegalArgumentException("Set of taskIds is empty");
}
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
List<VariableInstanceEntity> entities = processEngineConfiguration.getVariableServiceConfiguration().getVariableService()
.createInternalVariableInstanceQuery().taskIds(taskIds).list();
List<VariableInstance> instances = new ArrayList<>(entities.size());
for (VariableInstanceEntity entity : entities) {
entity.getValue();
instances.add(entity);
}
return instances;
}
}
View on GitHub (pinned to d6d39ce1c6)