apache/dolphinscheduler · error · ServiceException

USED_WORKER_GROUP_EXISTS

USED_WORKER_GROUP_EXISTS

Error message

Used worker group exists: ${usedInProject}

What it means

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).

Solutions

  1. Remove usage of the listed worker groups from the project's workflows first, then retry the assignment
  2. Exclude the used worker groups from the assign request
  3. Force-assign via updating workflow definitions to use the new group, then call the API

Example fix

// before
projectWorkerGroupService.assignWorkerGroupsToProject(loginUser, projectCode, allGroups); // includes in-use groups
// after
Set<String> used = getUsedWorkerGroups(projectCode);
Set<String> safe = allGroups.stream().filter(g -> !used.contains(g)).collect(Collectors.toSet());
projectWorkerGroupService.assignWorkerGroupsToProject(loginUser, projectCode, safe);
Defensive patterns

Strategy: validation

Validate before calling

Set<String> used = getAllUsedWorkerGroups(project);
Set<String> assigned = new HashSet<>(projectWorkerGroupDao.queryAssignedWorkerGroupNamesByProjectCode(projectCode));
Set<String> clash = Sets.intersection(used, requested);
if (!clash.isEmpty()) { throw new IllegalStateException("in use: " + clash); }

Try / catch

try {
    service.assignWorkerGroupsToProject(loginUser, projectCode, groups);
} catch (ServiceException e) {
    if (e.getCode() == Status.USED_WORKER_GROUP_EXISTS) {
        log.warn("Worker groups still in use: {}", e.getMessage());
        return result;
    }
    throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/aa41cf05df6c40c3. Report an issue: GitHub.

Appendix: source

Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProjectWorkerGroupRelationServiceImpl.java:113

        if (Objects.isNull(project)) {
            putMsg(result, Status.PROJECT_NOT_EXIST);
            return result;
        }

        /*
         * Todo : For modification operations on projects, we should acquire project row locks. All project-related
         * operations and modification/creation actions for workflows/task definitions within the project require
         * acquiring row locks first
         */
        if (CollectionUtils.isEmpty(workerGroups)) {
            Set<String> projectWorkerGroupNames =
                    projectWorkerGroupDao.queryAssignedWorkerGroupNamesByProjectCode(projectCode);
            if (CollectionUtils.isNotEmpty(projectWorkerGroupNames)) {
                Set<String> usedWorkerGroups = getAllUsedWorkerGroups(project);
                if (CollectionUtils.isNotEmpty(usedWorkerGroups)) {
                    Set<String> usedInProject = SetUtils.intersection(usedWorkerGroups, projectWorkerGroupNames);
                    if (!usedInProject.isEmpty()) {
                        throw new ServiceException(Status.USED_WORKER_GROUP_EXISTS, usedInProject);
                    }
                }
            }

            boolean deleted = projectWorkerGroupDao.deleteByProjectCode(projectCode);
            if (deleted) {
                putMsg(result, Status.SUCCESS);
            } else {
                putMsg(result, Status.ASSIGN_WORKER_GROUP_TO_PROJECT_ERROR);
            }
            return result;
        }

        Set<String> allWorkerGroupNames = new HashSet<>(workerGroupDao.queryAllWorkerGroupNames());
        workerGroupService.getConfigWorkerGroupPageDetail().forEach(
                workerGroupPageDetail -> allWorkerGroupNames.add(workerGroupPageDetail.getName()));
        Set<String> unauthorizedWorkerGroupNames = new HashSet<>(workerGroups);

View on GitHub (pinned to 02eac45a1b)