{"record":{"id":"e618f8914ffca967","repo":"flowable/flowable-engine","slug":"candidate-group-list-is-null-e618f8","errorCode":null,"errorMessage":"Candidate group list is null","messagePattern":"Candidate group list is null","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/TaskQueryImpl.java","lineNumber":552,"sourceCode":"        if (candidateUser != null) {\n            throw new ActivitiIllegalArgumentException(\"Invalid query usage: cannot set both candidateGroup and candidateUser\");\n        }\n\n        if (orActive) {\n            currentOrQueryObject.bothCandidateAndAssigned = true;\n            currentOrQueryObject.userIdForCandidateAndAssignee = userIdForCandidateAndAssignee;\n        } else {\n            this.bothCandidateAndAssigned = true;\n            this.userIdForCandidateAndAssignee = userIdForCandidateAndAssignee;\n        }\n\n        return this;\n    }\n\n    @Override\n    public TaskQuery taskCandidateGroupIn(List<String> candidateGroups) {\n        if (candidateGroups == null) {\n            throw new ActivitiIllegalArgumentException(\"Candidate group list is null\");\n        }\n\n        if (candidateGroups.isEmpty()) {\n            throw new ActivitiIllegalArgumentException(\"Candidate group list is empty\");\n        }\n\n        if (candidateGroup != null) {\n            throw new ActivitiIllegalArgumentException(\"Invalid query usage: cannot set both candidateGroupIn and candidateGroup\");\n        }\n\n        if (orActive) {\n            currentOrQueryObject.candidateGroups = candidateGroups;\n        } else {\n            this.candidateGroups = candidateGroups;\n        }\n        return this;\n    }\n","sourceCodeStart":534,"sourceCodeEnd":570,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/TaskQueryImpl.java#L534-L570","documentation":"TaskQueryImpl.taskCandidateGroupIn(List<String>) throws ActivitiIllegalArgumentException when the candidateGroups list is null. The Flowable/Activiti query API validates its arguments eagerly at query-build time so invalid queries fail immediately instead of producing confusing errors at list().call(). A null list carries no group filter, so it is rejected outright rather than silently ignored.","triggerScenarios":"Calling taskQuery.taskCandidateGroupIn(null), typically when the group list comes from a variable, config property, or upstream lookup that returned null.","commonSituations":"Building a dynamic task query where the candidate groups are loaded from a database, LDAP sync result, or optional request parameter that resolved to null; forgetting to default an uninitialized collection before querying.","solutions":["Ensure the list passed to taskCandidateGroupIn is non-null before building the query (initialize with Collections.emptyList() at the declaration site).","If groups are optional, branch: skip calling taskCandidateGroupIn entirely when the list is null instead of passing null.","Catch ActivitiIllegalArgumentException around the query construction to surface a user-facing message with the offending filter."],"exampleFix":"// before\nList<String> groups = loadGroups(userId);\ntaskQuery.taskCandidateGroupIn(groups);\n\n// after\nList<String> groups = loadGroups(userId);\nif (groups != null && !groups.isEmpty()) {\n    taskQuery.taskCandidateGroupIn(groups);\n}","handlingStrategy":"validation","validationCode":"if (candidateGroups == null) throw new IllegalArgumentException(\"candidateGroups must not be null\");\ntaskQuery.taskCandidateGroupIn(candidateGroups);","typeGuard":"boolean isValidGroupList(List<String> groups) { return groups != null && !groups.isEmpty(); }","tryCatchPattern":"try {\n    taskQuery.taskCandidateGroupIn(groups).list();\n} catch (ActivitiIllegalArgumentException e) {\n    log.warn(\"Invalid candidate group filter: {}\", e.getMessage());\n}","preventionTips":["Initialize collection fields with empty lists, never null","Validate all query inputs in one place before building queries","Treat optional filters as 'skip the call', not 'pass null'"],"tags":["activiti","flowable","task-query","argument-validation"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}