{"record":{"id":"aa41cf05df6c40c3","repo":"apache/dolphinscheduler","slug":"used-worker-group-exists","errorCode":"USED_WORKER_GROUP_EXISTS","errorMessage":"Used worker group exists: ${usedInProject}","messagePattern":"Used worker group exists: (.+?)","errorType":"error_code","errorClass":"ServiceException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProjectWorkerGroupRelationServiceImpl.java","lineNumber":113,"sourceCode":"        if (Objects.isNull(project)) {\n            putMsg(result, Status.PROJECT_NOT_EXIST);\n            return result;\n        }\n\n        /*\n         * Todo : For modification operations on projects, we should acquire project row locks. All project-related\n         * operations and modification/creation actions for workflows/task definitions within the project require\n         * acquiring row locks first\n         */\n        if (CollectionUtils.isEmpty(workerGroups)) {\n            Set<String> projectWorkerGroupNames =\n                    projectWorkerGroupDao.queryAssignedWorkerGroupNamesByProjectCode(projectCode);\n            if (CollectionUtils.isNotEmpty(projectWorkerGroupNames)) {\n                Set<String> usedWorkerGroups = getAllUsedWorkerGroups(project);\n                if (CollectionUtils.isNotEmpty(usedWorkerGroups)) {\n                    Set<String> usedInProject = SetUtils.intersection(usedWorkerGroups, projectWorkerGroupNames);\n                    if (!usedInProject.isEmpty()) {\n                        throw new ServiceException(Status.USED_WORKER_GROUP_EXISTS, usedInProject);\n                    }\n                }\n            }\n\n            boolean deleted = projectWorkerGroupDao.deleteByProjectCode(projectCode);\n            if (deleted) {\n                putMsg(result, Status.SUCCESS);\n            } else {\n                putMsg(result, Status.ASSIGN_WORKER_GROUP_TO_PROJECT_ERROR);\n            }\n            return result;\n        }\n\n        Set<String> allWorkerGroupNames = new HashSet<>(workerGroupDao.queryAllWorkerGroupNames());\n        workerGroupService.getConfigWorkerGroupPageDetail().forEach(\n                workerGroupPageDetail -> allWorkerGroupNames.add(workerGroupPageDetail.getName()));\n        Set<String> unauthorizedWorkerGroupNames = new HashSet<>(workerGroups);\n","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProjectWorkerGroupRelationServiceImpl.java#L95-L131","documentation":"Thrown in assignWorkerGroupsToProject when trying to (re)assign worker groups to a project while some of the groups to be assigned are still in use by workflows/process definitions in that project (intersection of used groups and already-assigned names is non-empty).","triggerScenarios":"Assigning a set of worker groups that includes a group currently referenced by a process definition of the same project — the service refuses the assignment/removal because it would orphan running definitions.","commonSituations":"Bulk re-assignment including groups still tagged in workflow definitions; cleaning up project worker-group relations without first editing workflows; automation scripts assigning the full group list.","solutions":["Remove usage of the listed worker groups from the project's workflows first, then retry the assignment","Exclude the used worker groups from the assign request","Force-assign via updating workflow definitions to use the new group, then call the API"],"exampleFix":"// before\nprojectWorkerGroupService.assignWorkerGroupsToProject(loginUser, projectCode, allGroups); // includes in-use groups\n// after\nSet<String> used = getUsedWorkerGroups(projectCode);\nSet<String> safe = allGroups.stream().filter(g -> !used.contains(g)).collect(Collectors.toSet());\nprojectWorkerGroupService.assignWorkerGroupsToProject(loginUser, projectCode, safe);","handlingStrategy":"validation","validationCode":"Set<String> used = getAllUsedWorkerGroups(project);\nSet<String> assigned = new HashSet<>(projectWorkerGroupDao.queryAssignedWorkerGroupNamesByProjectCode(projectCode));\nSet<String> clash = Sets.intersection(used, requested);\nif (!clash.isEmpty()) { throw new IllegalStateException(\"in use: \" + clash); }","typeGuard":null,"tryCatchPattern":"try {\n    service.assignWorkerGroupsToProject(loginUser, projectCode, groups);\n} catch (ServiceException e) {\n    if (e.getCode() == Status.USED_WORKER_GROUP_EXISTS) {\n        log.warn(\"Worker groups still in use: {}\", e.getMessage());\n        return result;\n    }\n    throw e;\n}","preventionTips":["Diff requested groups against workflow usages before assigning","Migrate workflow worker-group settings first","Never bulk-assign the full group list blindly"],"tags":["worker-group","project","conflict"],"backgroundTag":"conflicting-config-options","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}