flowable/flowable-engine · error · FlowableIllegalArgumentException
Candidate user is null
Error message
Candidate user is null
What it means
TaskQueryImpl.taskCandidateUser(String) rejects a null candidate user. The candidate-user filter drives the identity-link join in the query; a null user would produce meaningless SQL, so Flowable validates eagerly and throws FlowableIllegalArgumentException.
Solutions
- Resolve the user ID first (e.g. from the security context) and refuse to build the query when it is null.
- Skip the candidateUser filter when there is no user, using a different query strategy (e.g. by group or by process).
- Fix the authentication/user-resolution code so a real user ID is always available where this query runs.
Example fix
// before
taskQuery.taskCandidateUser(securityService.getCurrentUser());
// after
String userId = securityService.getCurrentUser();
if (userId != null) {
taskQuery.taskCandidateUser(userId);
} Defensive patterns
Strategy: validation
Validate before calling
if (candidateUser == null || candidateUser.isEmpty()) { throw new IllegalStateException("candidateUser required for this query"); }
taskQuery.taskCandidateUser(candidateUser); Type guard
boolean usable = candidateUser != null && !candidateUser.isEmpty();
Try / catch
try {
taskQuery.taskCandidateUser(userId);
} catch (FlowableIllegalArgumentException e) {
if (!"Candidate user is null".equals(e.getMessage())) throw e;
logger.warn("No authenticated user; cannot query candidate tasks");
return Collections.emptyList();
} Prevention
- Resolve the user ID from the security context before creating the query and handle 'no user' explicitly.
- Avoid running candidate-user queries in background jobs without a user context; use group or process-based queries instead.
- Fail fast at the controller/service boundary when a task inbox is requested without authentication.
When it happens
Trigger: taskQuery.taskCandidateUser(null) — typically when the current user is unknown: no authenticated principal, an unauthenticated request, or a user variable never set.
Common situations: Calling taskService.createTaskQuery().taskCandidateUser(userId) in a scheduled/background job with no user context; a security context returning null user in anonymous flows; upgrading or wiring identity services so userId is no longer populated.
Related errors
- Description is null
- Involved groups are null
- Involved user is null
- Max Priority is null
- Min Priority is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/84d31ab1e919ef35.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/TaskQueryImpl.java:578
if (delegationState == null) {
currentOrQueryObject.noDelegationState = true;
} else {
currentOrQueryObject.delegationState = delegationState;
}
} else {
if (delegationState == null) {
this.noDelegationState = true;
} else {
this.delegationState = delegationState;
}
}
return this;
}
@Override
public TaskQueryImpl taskCandidateUser(String candidateUser) {
if (candidateUser == null) {
throw new FlowableIllegalArgumentException("Candidate user is null");
}
if (orActive) {
currentOrQueryObject.candidateUser = candidateUser;
} else {
this.candidateUser = candidateUser;
}
return this;
}
@Override
public TaskQueryImpl taskInvolvedUser(String involvedUser) {
if (involvedUser == null) {
throw new FlowableIllegalArgumentException("Involved user is null");
}
if (orActive) {
currentOrQueryObject.involvedUser = involvedUser;View on GitHub (pinned to d6d39ce1c6)