flowable/flowable-engine · error · FlowableIllegalArgumentException
processInstanceIds is null
Error message
processInstanceIds is null
What it means
BulkDeleteHistoricProcessInstancesCmd.execute throws FlowableIllegalArgumentException when the collection of process instance ids passed to bulk-delete historic process instances is null. The bulk delete is a single history-recording operation, so it cannot proceed without an explicit id list.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/BulkDeleteHistoricProcessInstancesCmd.java:36
import org.flowable.common.engine.api.FlowableIllegalArgumentException;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.impl.util.CommandContextUtil;
public class BulkDeleteHistoricProcessInstancesCmd implements Command<Object>, Serializable {
private static final long serialVersionUID = 1L;
protected Collection<String> processInstanceIds;
public BulkDeleteHistoricProcessInstancesCmd(Collection<String> processInstanceIds) {
this.processInstanceIds = processInstanceIds;
}
@Override
public Object execute(CommandContext commandContext) {
if (processInstanceIds == null) {
throw new FlowableIllegalArgumentException("processInstanceIds is null");
}
if (processInstanceIds.isEmpty()) {
throw new FlowableIllegalArgumentException("processInstanceIds is empty");
}
CommandContextUtil.getHistoryManager(commandContext).recordBulkDeleteProcessInstances(processInstanceIds);
return null;
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Null-check the id collection before invoking the bulk delete and fail fast in your own code with a clear message.
- Ensure upstream queries return empty lists instead of null (initialize the list at declaration).
- If ids come from configuration/input, validate presence before calling the API.
- Wrap the call in try-catch for FlowableIllegalArgumentException only as a last-resort guard, not as control flow.
Example fix
// before
historyService.bulkDeleteHistoricProcessInstances(ids); // ids may be null
// after
if (ids == null) {
throw new IllegalArgumentException("processInstanceIds must not be null");
}
historyService.bulkDeleteHistoricProcessInstances(ids); Defensive patterns
Strategy: validation
Validate before calling
Objects.requireNonNull(processInstanceIds, "processInstanceIds must not be null");
Type guard
boolean isUsableIdList(List<String> ids) {
return ids != null && !ids.isEmpty();
} Try / catch
try {
historyService.bulkDeleteHistoricProcessInstances(ids);
} catch (FlowableIllegalArgumentException e) {
logger.error("Invalid argument for bulk historic delete: {}", e.getMessage());
} Prevention
- Initialize collections at declaration instead of leaving them null.
- Null-check parameters at API boundaries in your own service layer.
- Prefer returning empty lists over null from helper queries.
- Use Objects.requireNonNull early to fail fast with a clear message.
When it happens
Trigger: Calling runtimeService/historyService bulk delete historic process instances API (e.g. managementService or custom code constructing new BulkDeleteHistoricProcessInstancesCmd(null)) with a null List, commonly the result of an earlier query that returned null or an unset method parameter.
Common situations: Code paths where the id list comes from another query or a nullable variable and was never null-checked; Spring beans with optional parameters; refactors where a default empty list was replaced by null.
Related errors
- processInstanceIds is empty
- query is null
- Error retrieving app engine info
- No deployment id available
- No resource name available
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/b2e223fabef759e1.
Report an issue: GitHub.