flowable/flowable-engine · error · FlowableIllegalArgumentException

Involved user is null

Error message

Involved user is null

What it means

Flowable throws this FlowableIllegalArgumentException from TaskQueryImpl.taskInvolvedUser() when you pass a null involved user. Query setters validate arguments eagerly so invalid queries fail at build time instead of producing SQL errors or empty results at query time. The query cannot filter by involvement without a user identity.

Solutions

  1. Pass a non-null user id string to taskInvolvedUser().
  2. Check the value for null before building the query and skip the involvement filter if absent.
  3. If involvement is optional, build the query conditionally instead of always calling the setter.
  4. Fix the upstream source (config/variable/expression) that produces the null user id.

Example fix

// before
TaskQuery query = taskService.createTaskQuery().taskInvolvedUser(userId);
// after
TaskQuery query = taskService.createTaskQuery();
if (userId != null) {
    query = query.taskInvolvedUser(userId);
}
Defensive patterns

Strategy: validation

Validate before calling

if (involvedUser == null) {
    throw new IllegalArgumentException("involvedUser must be non-null before taskInvolvedUser()");
}
query.taskInvolvedUser(involvedUser);

Type guard

boolean isValidInvolvedUser(String u) { return u != null && !u.trim().isEmpty(); }

Try / catch

try {
    query.taskInvolvedUser(userId);
} catch (FlowableIllegalArgumentException e) {
    logger.warn("Invalid task query: {}", e.getMessage());
    query = taskService.createTaskQuery(); // rebuild without the bad filter
}

Prevention

When it happens

Trigger: Calling taskQuery.taskInvolvedUser(null), including when the user id comes from an uninitialized variable, an optional config value, or an expression that resolved to null.

Common situations: Variable holding the user id is null because a lookup failed; Spring @Value or process variable not populated; refactoring renamed a field leaving it unset; OR-query branches built dynamically where one branch yields null.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/da5d88f395f4d67b. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/TaskQueryImpl.java:593

    @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;
        } else {
            this.involvedUser = involvedUser;
        }
        return this;
    }

    @Override
    public TaskQueryImpl taskInvolvedGroups(Collection<String> involvedGroups) {
        if (involvedGroups == null) {
            throw new FlowableIllegalArgumentException("Involved groups are null");
        }
        if (involvedGroups.isEmpty()) {
            throw new FlowableIllegalArgumentException("Involved groups are empty");
        }
        if (orActive) {

View on GitHub (pinned to d6d39ce1c6)