flowable/flowable-engine · error · FlowableIllegalArgumentException
query is null
Error message
query is null
What it means
DeleteHistoricProcessInstancesCmd bulk-deletes historic process instances matching a HistoricProcessInstanceQuery; it validates the query object is non-null. A null query means nothing to evaluate, so the engine throws FlowableIllegalArgumentException immediately.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/DeleteHistoricProcessInstancesCmd.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.HistoricProcessInstanceQueryImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
public class DeleteHistoricProcessInstancesCmd implements Command<Object>, Serializable {
private static final long serialVersionUID = 1L;
protected HistoricProcessInstanceQueryImpl historicProcessInstanceQuery;
public DeleteHistoricProcessInstancesCmd(HistoricProcessInstanceQueryImpl historicProcessInstanceQuery) {
this.historicProcessInstanceQuery = historicProcessInstanceQuery;
}
@Override
public Object execute(CommandContext commandContext) {
if (historicProcessInstanceQuery == null) {
throw new FlowableIllegalArgumentException("query is null");
}
CommandContextUtil.getHistoricProcessInstanceEntityManager(commandContext).deleteHistoricProcessInstances(historicProcessInstanceQuery);
return null;
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Create a query object first: historyService.createHistoricProcessInstanceQuery() and apply criteria before passing it
- Guard the call with a null check on the query
- Initialize the query field at construction instead of lazily
Example fix
// before
historyService.deleteHistoricProcessInstances(query); // query was null
// after
HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery()
.finished().before(new Date());
historyService.deleteHistoricProcessInstances(query); Defensive patterns
Strategy: validation
Validate before calling
if (query == null) {
throw new IllegalArgumentException("A HistoricProcessInstanceQuery is required for bulk delete");
} Type guard
boolean isValidQuery = q -> q instanceof HistoricProcessInstanceQuery;
Try / catch
try {
historyService.deleteHistoricProcessInstances(query);
} catch (FlowableIllegalArgumentException e) {
logger.error("Bulk delete called without a query", e);
} Prevention
- Build the query in the same scope as the delete call
- Never pass null as a 'delete all' shorthand; there is no such API
- Initialize query fields eagerly in classes that own deletion logic
When it happens
Trigger: historyService.deleteHistoricProcessInstances(query) (or the bulk variant via management APIs) where the query variable is null, e.g. a builder method returned null or a field was never initialized before deletion.
Common situations: Programmatic query construction where a branch skips creating the query, refactoring that removed query creation, or passing null intentionally as 'delete all' which the API does not accept.
Related errors
- processInstanceIds is null
- query is null
- Must specify a historic case instance id to migrate
- Set of process instance ids is null
- Set of called process instance ids is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/ee597811fb76fe67.
Report an issue: GitHub.