{"record":{"id":"2898b4e7f7fa28f8","repo":"theonedev/onedev","slug":"assignee-needs-to-have-write-code-permission-to-th","errorCode":null,"errorMessage":"Assignee needs to have write code permission to the project","messagePattern":"Assignee needs to have write code permission to the project","errorType":"http","errorClass":"NotAcceptableException","httpStatus":406,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/PullRequestResource.java","lineNumber":448,"sourceCode":"\t\t\t\tthrow new NotAcceptableException(\"This reviewer is mandatory and cannot be removed\");\n\t\t\tpullRequestReviewService.createOrUpdate(user, review);\n\t\t}\n\n\t\treturn Response.ok().build();\t\n\t}\n\n\t@Api(order=1480)\n\t@Path(\"/{requestId}/assignees/{userId}\")\n\t@POST\n\tpublic Response addAssignee(@PathParam(\"requestId\") Long requestId, @PathParam(\"userId\") Long userId) {\n\t\tvar request = pullRequestService.load(requestId);\n\t\tvar user = userService.load(userId);\n\n\t\tif (!SecurityUtils.canModifyPullRequest(request))\n\t\t\tthrow new UnauthorizedException();\n\n\t\tif (!SecurityUtils.canWriteCode(user.asSubject(), request.getProject()))\n\t\t\tthrow new NotAcceptableException(\"Assignee needs to have write code permission to the project\");\n\n\t\tif (request.getAssignees().contains(user))\n\t\t\treturn Response.ok().build();\n\n\t\tvar assignment = new PullRequestAssignment();\n\t\tassignment.setRequest(request);\n\t\tassignment.setUser(user);\n\t\tpullRequestAssignmentService.create(assignment);\n\n\t\treturn Response.ok().build();\n\t}\n\n\t@Api(order=1490)\n\t@Path(\"/{requestId}/assignees/{userId}\")\n\t@DELETE\n\tpublic Response removeAssignee(@PathParam(\"requestId\") Long requestId, @PathParam(\"userId\") Long userId) {\n\t\tvar request = pullRequestService.load(requestId);\n\t\tvar user = userService.load(userId);","sourceCodeStart":430,"sourceCodeEnd":466,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/PullRequestResource.java#L430-L466","documentation":"NotAcceptableException (HTTP 400) thrown when the user being assigned lacks write-code permission on the pull request's target project. An assignee is expected to work on the code, so OneDev refuses users without at least Developer/Writer access. This validates the nominated user's permissions, not the caller's.","triggerScenarios":"POST .../assignees/{userId} where SecurityUtils.canWriteCode(user.asSubject(), request.getProject()) is false — the nominated user has no write (Developer+) role on the target project.","commonSituations":"Assigning a QA or read-only stakeholder; user belongs to another project; project roles changed so the user lost Developer access; scripts assign arbitrary user IDs.","solutions":["Grant the nominated user write-code (Developer) permission on the target project, then retry.","Assign a user who already has write access.","Reassign via a group that carries Developer role on the project."],"exampleFix":"// before\nPOST .../pull-requests/42/assignees/107 -> 400 Assignee needs write code permission\n// after: grant user 107 Developer role on the project, then\nPOST .../pull-requests/42/assignees/107 -> 200 OK","handlingStrategy":"validation","validationCode":"const canWrite = await onedevApi.projectQueryPermission(projectId, \"WRITE_CODE\", candidateUserId);\nif (!canWrite) throw new Error(`User ${candidateUserId} lacks WRITE_CODE on project ${projectId}; grant Developer role first`);","typeGuard":null,"tryCatchPattern":"try {\n  await api.addAssignee(requestId, userId);\n} catch (e) {\n  if (e.status === 400 && /write code permission/.test(e.body)) {\n    // grant Developer role or select a different assignee\n  } else throw e;\n}","preventionTips":["Only assign users with Developer+ access on the target project","Keep the assignee picker filtered by project write permission","Catch HTTP 400 and explain the required permission in tooling"],"tags":["rest","permissions","pull-request"],"backgroundTag":"insufficient-permissions","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}