{"record":{"id":"2a2ee3f005f311a0","repo":"flowable/flowable-engine","slug":"invalid-query-usage-cannot-set-candidategroup","errorCode":null,"errorMessage":"Invalid query usage: cannot set candidateGroup","messagePattern":"Invalid query usage: cannot set candidateGroup","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/TaskQueryImpl.java","lineNumber":640,"sourceCode":"            throw new FlowableIllegalArgumentException(\"Candidate group is null\");\n        }\n\n        if (candidateGroups != null) {\n            throw new FlowableIllegalArgumentException(\"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 FlowableIllegalArgumentException(\"Invalid query usage: cannot set candidateGroup\");\n        }\n        if (candidateUser != null) {\n            throw new FlowableIllegalArgumentException(\"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(Collection<String> candidateGroups) {","sourceCodeStart":622,"sourceCodeEnd":658,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/TaskQueryImpl.java#L622-L658","documentation":"TaskQueryImpl.taskCandidateOrAssigned() throws this when candidateGroup was already set on the query. candidateOrAssigned filters by candidate user and/or assignee, which is incompatible with a candidate-group filter on the same query. The conflict is detected eagerly at build time.","triggerScenarios":"Calling taskQuery.taskCandidateOrAssigned(userId) after taskCandidateGroup(\"g\"), including state left from a reused query object or an or() branch where candidateGroup was set first.","commonSituations":"Combining query-building code paths for group-based and user-based task assignment; reusing a TaskQuery across iterations; conditional logic that sets candidateGroup for some inputs then falls through to candidateOrAssigned.","solutions":["Remove one of the conflicting setters; keep either candidateGroup or candidateOrAssigned.","Create a new query instance per request to avoid leftover state.","If both group and user filtering are needed, run two queries or use or() semantics deliberately with only compatible criteria.","Restructure the builder so the group filter branch excludes the candidateOrAssigned branch."],"exampleFix":"// before\nquery.taskCandidateGroup(\"management\");\nquery.taskCandidateOrAssigned(userId);\n// after\nTaskQuery query = taskService.createTaskQuery();\nif (useGroupFilter) {\n    query.taskCandidateGroup(\"management\");\n} else {\n    query.taskCandidateOrAssigned(userId);\n}","handlingStrategy":"validation","validationCode":"if (useGroupFilter) {\n    query.taskCandidateGroup(group);\n} else {\n    query.taskCandidateOrAssigned(userId);\n}","typeGuard":null,"tryCatchPattern":"try {\n    query.taskCandidateOrAssigned(userId);\n} catch (FlowableIllegalArgumentException e) {\n    logger.warn(\"candidateGroup already set: {}\", e.getMessage());\n    query = taskService.createTaskQuery();\n}","preventionTips":["Set only one candidate-related filter per query (candidateGroup, candidateUser, candidateGroupIn, candidateOrAssigned)","Rebuild queries instead of mutating reused ones","Document filter exclusivity in shared query-builder utilities","Add regression tests for combined-filter scenarios"],"tags":["flowable","task-query","mutually-exclusive","candidate-group"],"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"}