flowable/flowable-engine · error · ActivitiIllegalArgumentException

Involved user is null

Error message

Involved user is null

What it means

taskInvolvedUser(String involvedUser) throws ActivitiIllegalArgumentException("Involved user is null") when the involved-user id is null. Involvement is stored via identity links, and the query needs a concrete user id to filter on. A null argument is rejected at builder time.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/TaskQueryImpl.java:501

    @Override
    public TaskQueryImpl taskCandidateUser(String candidateUser) {
        if (candidateUser == null) {
            throw new ActivitiIllegalArgumentException("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 ActivitiIllegalArgumentException("Involved user is null");
        }
        if (orActive) {
            currentOrQueryObject.involvedUser = involvedUser;
        } else {
            this.involvedUser = involvedUser;
        }
        return this;
    }

    @Override
    public TaskQueryImpl 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

  1. Null-check the involved user and add the filter only when present
  2. Have the API/DTO layer require the parameter explicitly when filtering by involvement is intended
  3. Clean up or guard lookups of users that may have been deleted

Example fix

// before
query.taskInvolvedUser(request.getParameter("involvedUser")); // null if param absent
// after
String involvedUser = request.getParameter("involvedUser");
if (involvedUser != null) { query.taskInvolvedUser(involvedUser); }
Defensive patterns

Strategy: validation

Validate before calling

if (involvedUser == null) {
    throw new IllegalArgumentException("involvedUser is required when filtering by involvement");
}
query.taskInvolvedUser(involvedUser);

Type guard

boolean hasInvolvedUser(String userId) { return userId != null && !userId.trim().isEmpty(); }

Try / catch

try {
    query.taskInvolvedUser(involvedUser);
} catch (ActivitiIllegalArgumentException e) {
    log.warn("Skipping involved-user filter: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling taskQuery.taskInvolvedUser(null), e.g. when the involved user id comes from an optional variable, request parameter, or lookup that was null.

Common situations: Passing a variable that was never set on the process; REST query endpoints where the involvedUser parameter was omitted; user directory lookups returning null for deleted users.

Related errors


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