{"record":{"id":"2ed08ea795295f4b","repo":"theonedev/onedev","slug":"you-are-not-reviewer-of-this-pull-request-add-you","errorCode":null,"errorMessage":"You are not reviewer of this pull request. Add your option as comment instead","messagePattern":"You are not reviewer of this pull request\\. Add your option as comment instead","errorType":"validation","errorClass":"NotAcceptableException","httpStatus":400,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/service/impl/DefaultPullRequestReviewService.java","lineNumber":80,"sourceCode":"\t\t\n\t\tRoot<PullRequestReview> root = query.from(PullRequestReview.class);\n\t\tquery.select(root);\n\t\tJoin<PullRequest, PullRequest> join = root.join(PullRequestReview.PROP_REQUEST);\n\t\tquery.where(join.in(requests));\n\t\t\n\t\tfor (PullRequest request: requests) \n\t\t\trequest.setReviews(new ArrayList<>());\n\t\t\n\t\tfor (PullRequestReview review: getSession().createQuery(query).getResultList())\n\t\t\treview.getRequest().getReviews().add(review);\n\t}\n \t\n\t@Transactional\n\t@Override\n\tpublic void review(User user, PullRequest request, boolean approved, String note) {\n\t\tPullRequestReview review = request.getReview(user);\n\t\tif (review == null || review.getStatus() == PullRequestReview.Status.EXCLUDED)\n\t\t\tthrow new NotAcceptableException(\"You are not reviewer of this pull request. Add your option as comment instead\");\n\n\t\tif (approved)\n\t\t\treview.setStatus(PullRequestReview.Status.APPROVED);\n\t\telse\n\t\t\treview.setStatus(PullRequestReview.Status.REQUESTED_FOR_CHANGES);\n\t\t\t\n\t\tcreateOrUpdate(user, review);\n\t\t\n\t\tPullRequestChange change = new PullRequestChange();\n\t\tchange.setDate(review.getStatusDate());\n\t\tchange.setRequest(request);\n\t\tchange.setUser(user);\n\t\tif (approved)\n\t\t\tchange.setData(new PullRequestApproveData());\n\t\telse\n\t\t\tchange.setData(new PullRequestRequestedForChangesData());\n\t\t\n\t\tchangeService.create(change, note);","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/service/impl/DefaultPullRequestReviewService.java#L62-L98","documentation":"Thrown by DefaultPullRequestReviewService.review when the acting user is not an assigned reviewer (or their review was EXCLUDED) on the pull request. Only invited reviewers can record approve/request-changes verdicts; everyone else must voice their opinion via comments. It surfaces as a NotAcceptableException (HTTP 405/400-class client error).","triggerScenarios":"Calling review(user, request, approved, note) (directly or via REST endpoint) when request.getReview(user) returns null or a review whose status is PullRequestReview.Status.EXCLUDED — i.e. user was never added as a reviewer or was removed/excluded from review.","commonSituations":"A developer tries to approve a colleague's PR via API without being added to the reviewer list; a reviewer was excluded by a code-compliance rule and then attempts to re-approve; scripting against the REST resource with a non-reviewer account.","solutions":["Have the PR author or a project admin add the user as a reviewer, then call review again","If the user should not be a reviewer, post their feedback as a comment on the pull request instead","Check request.getReview(user) before calling review to detect the null/EXCLUDED case","Verify you are authenticating as the intended user (token/account mix-up)"],"exampleFix":"// before\nreviewService.review(user, request, true, \"LGTM\"); // 405 if not reviewer\n// after\nif (request.getReview(user) != null && request.getReview(user).getStatus() != PullRequestReview.Status.EXCLUDED)\n    reviewService.review(user, request, true, \"LGTM\");\nelse\n    commentService.comment(user, request, \"LGTM\"); // add as comment instead","handlingStrategy":"try-catch","validationCode":"PullRequestReview review = request.getReview(currentUser);\nboolean canReview = review != null && review.getStatus() != PullRequestReview.Status.EXCLUDED;","typeGuard":"boolean isReviewer(PullRequest request, User user) {\n    PullRequestReview r = request.getReview(user);\n    return r != null && r.getStatus() != PullRequestReview.Status.EXCLUDED;\n}","tryCatchPattern":"try {\n    reviewService.review(user, request, approved, note);\n} catch (NotAcceptableException e) {\n    // fall back to posting a comment instead\n}","preventionTips":["Check reviewer assignment before invoking review APIs","Ensure the authenticated account is the intended reviewer","Post non-reviewer feedback as comments"],"tags":["pull-request","review","authorization"],"backgroundTag":"permission-denied","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}