flowable/flowable-engine · error · ActivitiIllegalArgumentException
Candidate user is null
Error message
Candidate user is null
What it means
HistoricTaskInstanceQueryImpl.taskCandidateUser(String) requires a non-null candidateUser. Since a null candidate would produce an ill-defined candidate filter, the engine throws ActivitiIllegalArgumentException immediately.
Source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/HistoricTaskInstanceQueryImpl.java:1067
@Override
public HistoricTaskInstanceQuery withoutDueDate() {
return withoutTaskDueDate();
}
@Override
public HistoricTaskInstanceQuery taskCategory(String category) {
if (inOrStatement) {
this.currentOrQueryObject.category = category;
} else {
this.category = category;
}
return this;
}
@Override
public HistoricTaskInstanceQuery taskCandidateUser(String candidateUser) {
if (candidateUser == null) {
throw new ActivitiIllegalArgumentException("Candidate user is null");
}
if (inOrStatement) {
this.currentOrQueryObject.candidateUser = candidateUser;
} else {
this.candidateUser = candidateUser;
}
return this;
}
@Override
public HistoricTaskInstanceQuery taskCandidateGroup(String candidateGroup) {
if (candidateGroup == null) {
throw new ActivitiIllegalArgumentException("Candidate group is null");
}
if (candidateGroups != null) {
throw new ActivitiIllegalArgumentException("Invalid query usage: cannot set both candidateGroup and candidateGroupIn");View on GitHub (pinned to d6d39ce1c6)
Solutions
- Check for null and skip the taskCandidateUser(...) call when there is no candidate user to filter on.
- Default the value to a concrete user id if a default is meaningful in your domain.
- Fail earlier in your own layer with a clear message if a candidate user is required for the operation.
Example fix
// before
String user = request.getParameter("candidateUser");
query.taskCandidateUser(user); // NPE risk -> throws when null
// after
String user = request.getParameter("candidateUser");
if (user != null) {
query.taskCandidateUser(user);
} Defensive patterns
Strategy: validation
Validate before calling
// Java
if (candidateUser != null && !candidateUser.isEmpty()) {
query.taskCandidateUser(candidateUser);
} Try / catch
try {
query.taskCandidateUser(candidateUser);
} catch (org.activiti.engine.ActivitiIllegalArgumentException e) {
// treat as 'no candidate user filter' or reject the request upstream
} Prevention
- Sanitize optional request parameters before passing them into query setters.
- Resolve the current user before building candidate-user queries.
- Never forward possibly-null variables straight into Flowable/Activiti query setters.
When it happens
Trigger: Calling taskCandidateUser(null) directly, or passing a variable/parameter that is null (e.g. an unset request parameter or lookup result).
Common situations: REST/Service-layer code forwarding an optional 'candidateUser' request param straight into the query; a user-context object that is null for anonymous requests.
Related errors
- Candidate group is null
- Candidate group list is null
- DeploymentId is null
- Error retrieving app engine info
- No deployment id available
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/35945d3a05c4d6bb.
Report an issue: GitHub.