apache/dolphinscheduler · error · ServiceException

30003

30003

Error message

user [{userName}] does not have write permission for project [{projectCode}]

What it means

Thrown by requireProjectPerm when writePermission is requested and the caller's project relation perm is not Constants.DEFAULT_ADMIN_PERMISSION (2, i.e. read-write). The user can see the project but holds read-only permission, so write operations on task groups are refused. Reported as Status.USER_NO_WRITE_PROJECT_PERM (code 30003) with userName and projectCode interpolated.

Source

Thrown at dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/TaskGroupServiceImpl.java:298

        Project project = projectDao.queryByCode(projectCode);
        if (project == null) {
            log.warn("Project does not exist, projectCode:{}.", projectCode);
            throw new ServiceException(Status.PROJECT_NOT_FOUND, projectCode);
        }
        if (project.getUserId().equals(loginUser.getId())) {
            return;
        }
        ProjectUser projectUser = projectUserDao.queryProjectRelation(project.getId(), loginUser.getId());
        if (projectUser == null) {
            log.warn("User {} does not have operation permission for project {}", loginUser.getUserName(),
                    project.getCode());
            throw new ServiceException(Status.USER_NO_OPERATION_PROJECT_PERM, loginUser.getUserName(),
                    project.getCode());
        }
        if (writePermission && projectUser.getPerm() != Constants.DEFAULT_ADMIN_PERMISSION) {
            log.warn("User {} does not have write permission for project {}", loginUser.getUserName(),
                    project.getCode());
            throw new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM, loginUser.getUserName(),
                    project.getCode());
        }
    }
}

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Ask an admin to upgrade the user's project permission to read-write (perm = 2 / DEFAULT_ADMIN_PERMISSION).
  2. Have the project owner perform the write operation.
  3. Check the perm column in t_ds_relation_project_user for this user/project pair.
  4. Use read-only APIs (queryTaskGroupByProjectCode with writePermission=false) if only listing is needed.

Example fix

// before
// read-only user attempts create
taskGroupService.createTaskGroup(loginUser, name, desc, total, projectCode);
// after
ProjectUser rel = projectUserDao.queryProjectRelation(project.getId(), loginUser.getId());
boolean canWrite = loginUser.getUserType() == UserType.ADMIN_USER
        || project.getUserId().equals(loginUser.getId())
        || (rel != null && rel.getPerm() == Constants.DEFAULT_ADMIN_PERMISSION);
if (!canWrite) {
    throw new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM,
            loginUser.getUserName(), project.getCode());
}
Defensive patterns

Strategy: validation

Validate before calling

// Java: verify read-write permission before write operations
ProjectUser rel = projectUserDao.queryProjectRelation(project.getId(), loginUser.getId());
boolean canWrite = loginUser.getUserType() == UserType.ADMIN_USER
        || project.getUserId().equals(loginUser.getId())
        || (rel != null && rel.getPerm() == Constants.DEFAULT_ADMIN_PERMISSION);
if (!canWrite) throw new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM,
        loginUser.getUserName(), project.getCode());

Type guard

boolean hasProjectWriteAccess(User loginUser, Project project) {
    ProjectUser rel = projectUserDao.queryProjectRelation(project.getId(), loginUser.getId());
    return loginUser.getUserType() == UserType.ADMIN_USER
            || project.getUserId().equals(loginUser.getId())
            || (rel != null && rel.getPerm() == Constants.DEFAULT_ADMIN_PERMISSION);
}

Try / catch

try {
    taskGroupService.createTaskGroup(loginUser, name, desc, total, projectCode);
} catch (ServiceException e) {
    if (e.getCode() == 30003) {
        // ask an admin to upgrade the grant to read-write (perm = 2)
    }
    throw e;
}

Prevention

When it happens

Trigger: createTaskGroup or updateTaskGroup called by a user whose projectUser.getPerm() is read-only (not 2); queryTaskGroupByProjectCode with writePermission=false never hits this; read-only grantees attempting to modify task group config.

Common situations: User granted 'view only' project permission trying to create task groups; permission downgraded to read-only by an admin while user's scripts still write; confusing read access with write access when designing roles.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


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