{"record":{"id":"2cfe570e6f5f485e","repo":"apache/dolphinscheduler","slug":"user-no-write-project-perm","errorCode":"USER_NO_WRITE_PROJECT_PERM","errorMessage":"USER_NO_WRITE_PROJECT_PERM: user ${userName} has no write permission for project ${projectCode}","messagePattern":"USER_NO_WRITE_PROJECT_PERM: user (.+?) has no write permission for project (.+?)","errorType":"error_code","errorClass":"ServiceException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProjectServiceImpl.java","lineNumber":224,"sourceCode":"    }\n\n    @Override\n    public void checkHasProjectWritePermissionThrowException(User loginUser, Project project) {\n        if (project == null) {\n            throw new ServiceException(Status.PROJECT_NOT_FOUND, null);\n        }\n        // case 1: user is admin\n        if (loginUser.getUserType() == UserType.ADMIN_USER) {\n            return;\n        }\n        // case 2: user is project owner\n        if (project.getUserId().equals(loginUser.getId())) {\n            return;\n        }\n        // case 3: check user permission level\n        ProjectUser projectUser = projectUserDao.queryProjectRelation(project.getId(), loginUser.getId());\n        if (projectUser == null || projectUser.getPerm() != Constants.DEFAULT_ADMIN_PERMISSION) {\n            throw new ServiceException(Status.USER_NO_WRITE_PROJECT_PERM, loginUser.getUserName(), project.getCode());\n        }\n    }\n\n    /**\n     * admin can view all projects\n     *\n     * @param loginUser login user\n     * @param searchVal search value\n     * @param pageSize  page size\n     * @param pageNo    page number\n     * @return project list which the login user have permission to see\n     */\n    @Override\n    public Result queryProjectListPaging(User loginUser, Integer pageSize, Integer pageNo, String searchVal) {\n        Result result = new Result();\n        PageInfo<Project> pageInfo = new PageInfo<>(pageNo, pageSize);\n        Page<Project> page = new Page<>(pageNo, pageSize);\n        Set<Integer> projectIds = resourcePermissionCheckService","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProjectServiceImpl.java#L206-L242","documentation":"Thrown by checkHasProjectWritePermissionThrowException when the user is not an admin, not the project owner, and has no PROJECT-perm-level relation with the project (or lacks DEFAULT_ADMIN_PERMISSION on that relation). Message interpolates userName and projectCode.","triggerScenarios":"A regular user without an adequate projectUser row calls any write operation (edit project, save workflow, etc.) guarded by this check on a project owned by someone else.","commonSituations":"Collaborator was granted only read access; grant was revoked; user switched accounts; project ownership transferred to another user.","solutions":["Grant the user write/admin-level permission on the project (DEFAULT_ADMIN_PERMISSION in t_ds_relation_project_user)","Ask the project owner or an admin to perform the operation","Transfer project ownership if the operation should belong to this user"],"exampleFix":"// before\n// no check; service call fails\nprojectService.checkHasProjectWritePermissionThrowException(loginUser, project);\n// after\nProjectUser pu = projectUserDao.queryProjectRelation(project.getId(), loginUser.getId());\nif (loginUser.getUserType() != UserType.ADMIN_USER && pu != null && pu.getPerm() != Constants.DEFAULT_ADMIN_PERMISSION) {\n    pu.setPerm(Constants.DEFAULT_ADMIN_PERMISSION);\n    projectUserDao.updateById(pu);\n}\nprojectService.checkHasProjectWritePermissionThrowException(loginUser, project);","handlingStrategy":"validation","validationCode":"ProjectUser pu = projectUserDao.queryProjectRelation(project.getId(), loginUser.getId());\nboolean canWrite = loginUser.getUserType() == UserType.ADMIN_USER\n        || project.getUserId().equals(loginUser.getId())\n        || (pu != null && pu.getPerm() == Constants.DEFAULT_ADMIN_PERMISSION);","typeGuard":"boolean isOwner = loginUser != null && loginUser.getId().equals(project.getUserId());","tryCatchPattern":"try {\n    service.checkHasProjectWritePermissionThrowException(loginUser, project);\n} catch (ServiceException e) {\n    if (e.getCode() == Status.USER_NO_WRITE_PROJECT_PERM) {\n        putMsg(result, e.getCode(), loginUser.getUserName(), project.getCode());\n        return result;\n    }\n    throw e;\n}","preventionTips":["Check the projectUser relation perm before write APIs","Request write grants from project owners for collaborators","Prefer owner or admin accounts for maintenance operations"],"tags":["api","project","authorization","write-permission"],"backgroundTag":"insufficient-permissions","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}