{"record":{"id":"0c610e55acffd116","repo":"flowable/flowable-engine","slug":"invalid-query-usage-cannot-set-both-candidategrou-0c610e","errorCode":null,"errorMessage":"Invalid query usage: cannot set both candidateGroup and candidateGroupIn","messagePattern":"Invalid query usage: cannot set both candidateGroup and candidateGroupIn","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/TaskQueryImpl.java","lineNumber":518,"sourceCode":"        if (involvedUser == null) {\n            throw new ActivitiIllegalArgumentException(\"Involved user is null\");\n        }\n        if (orActive) {\n            currentOrQueryObject.involvedUser = involvedUser;\n        } else {\n            this.involvedUser = involvedUser;\n        }\n        return this;\n    }\n\n    @Override\n    public TaskQueryImpl taskCandidateGroup(String candidateGroup) {\n        if (candidateGroup == null) {\n            throw new ActivitiIllegalArgumentException(\"Candidate group is null\");\n        }\n\n        if (candidateGroups != null) {\n            throw new ActivitiIllegalArgumentException(\"Invalid query usage: cannot set both candidateGroup and candidateGroupIn\");\n        }\n\n        if (orActive) {\n            currentOrQueryObject.candidateGroup = candidateGroup;\n        } else {\n            this.candidateGroup = candidateGroup;\n        }\n        return this;\n    }\n\n    @Override\n    public TaskQuery taskCandidateOrAssigned(String userIdForCandidateAndAssignee) {\n        if (candidateGroup != null) {\n            throw new ActivitiIllegalArgumentException(\"Invalid query usage: cannot set candidateGroup\");\n        }\n        if (candidateUser != null) {\n            throw new ActivitiIllegalArgumentException(\"Invalid query usage: cannot set both candidateGroup and candidateUser\");\n        }","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/TaskQueryImpl.java#L500-L536","documentation":"taskCandidateGroup(String candidateGroup) throws this error when candidateGroups (the list set via taskCandidateGroupIn) is already populated. A single candidate group and a candidate-group list are mutually exclusive filters; both would produce conflicting identity-link conditions. Remove one of the two calls.","triggerScenarios":"Calling taskQuery.taskCandidateGroup(\"hr\") after taskQuery.taskCandidateGroupIn(list) on the same query object (or same OR block). The check compares against the candidateGroups field at TaskQueryImpl.java:518.","commonSituations":"Composing queries from layered services that each add their own group filter; migrating from a single group to a group list while keeping the old call; generic search forms that support both modes without resetting the query.","solutions":["Use taskCandidateGroupIn(list) exclusively, with the single group wrapped in a one-element list","Rebuild the query instead of reusing a partially configured TaskQueryImpl","Centralize candidate-group filtering in one helper that picks either single or list mode"],"exampleFix":"// before\nquery.taskCandidateGroupIn(groupList);\nquery.taskCandidateGroup(\"hr\"); // throws\n// after\nList<String> groups = new ArrayList<>(groupList);\ngroups.add(\"hr\");\nquery.taskCandidateGroupIn(groups);","handlingStrategy":"validation","validationCode":"if (singleGroup != null && groupList != null) {\n    throw new IllegalStateException(\"Use either taskCandidateGroup or taskCandidateGroupIn, not both\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    query.taskCandidateGroup(singleGroup);\n} catch (ActivitiIllegalArgumentException e) {\n    log.warn(\"Candidate group filters conflict: {}\", e.getMessage());\n    query = taskService.createTaskQuery().taskCandidateGroupIn(groupList);\n}","preventionTips":["Normalize all group filters to taskCandidateGroupIn with a list, wrapping single values","Never reuse a partially configured TaskQuery object; create a fresh query per request","Pick a single candidate-group filtering strategy in your query-building layer"],"tags":["task-query","mutually-exclusive","candidate-group","activiti"],"backgroundTag":"mutually-exclusive-options","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"}