{"record":{"id":"955f82a1a54ff82e","repo":"theonedev/onedev","slug":"this-pull-request-is-not-eligible-for-auto-merge-955f82","errorCode":null,"errorMessage":"This pull request is not eligible for auto-merge, as it can be merged directly now","messagePattern":"This pull request is not eligible for auto-merge, as it can be merged directly now","errorType":"http","errorClass":"NotAcceptableException","httpStatus":406,"severity":"warning","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/PullRequestResource.java","lineNumber":509,"sourceCode":"\t\t\tthrow new NotAcceptableException(\"Pull request is closed\");\n\t\tpullRequestChangeService.changeMergeStrategy(user, request, mergeStrategy);\n\t\treturn Response.ok().build();\n    }\n\t\n\t@Api(order=1550)\n\t@Path(\"/{requestId}/auto-merge\")\n\t@POST\n\tpublic Response setAutoMerge(@PathParam(\"requestId\") Long requestId, @NotNull AutoMergeData data) {\n\t\tvar subject = SecurityUtils.getSubject();\n\t\tvar user = SecurityUtils.getUser(subject);\n\t\tPullRequest request = pullRequestService.load(requestId);\n\t\tif (!SecurityUtils.canModifyPullRequest(subject, request) || !SecurityUtils.canWriteCode(subject, request.getProject()))\n\t\t\tthrow new UnauthorizedException();\n\t\tif (!request.isOpen())\n\t\t\tthrow new NotAcceptableException(\"Pull request is closed\");\n\n\t\tif (data.isEnabled() && request.checkMergeCondition() == null)\n\t\t\tthrow new NotAcceptableException(\"This pull request is not eligible for auto-merge, as it can be merged directly now\");\n\n\t\tvar autoMerge = new AutoMerge();\n\t\tautoMerge.setEnabled(data.isEnabled());\n\t\tautoMerge.setCommitMessage(data.getCommitMessage());\n\t\tvar errorMessage = request.checkMergeCommitMessage(user, autoMerge.getCommitMessage());\n\t\tif (errorMessage != null)\n\t\t\tthrow new NotAcceptableException(\"Error validating auto merge commit message: \" + errorMessage);\n\n\t\tpullRequestChangeService.changeAutoMerge(user, request, autoMerge);\n\n\t\treturn Response.ok().build();\n\t}\n\t\n\t@Api(order=1600)\n\t@Path(\"/{requestId}/reopen\")\n    @POST\n    public Response reopenPullRequest(@PathParam(\"requestId\") Long requestId, String note) {\n\t\tPullRequest request = pullRequestService.load(requestId);","sourceCodeStart":491,"sourceCodeEnd":527,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/PullRequestResource.java#L491-L527","documentation":"Thrown by POST /pull-requests/{requestId}/auto-merge when enabling auto-merge on a PR that already satisfies its merge condition, meaning it can be merged immediately and auto-merge is pointless. OneDev deliberately rejects this via NotAcceptableException (HTTP 406) to force a direct merge instead.","triggerScenarios":"POSTing {enabled:true} to /~api/pull-requests/{requestId}/auto-merge when request.checkMergeCondition() returns null — i.e. no build failures, no unresolved required reviews, branch up to date, all merge prerequisites already met.","commonSituations":"Enabling auto-merge by default in scripts even for PRs whose CI already passed and reviews are complete; race where the last blocking condition clears just before the auto-merge call; automation that should merge directly instead of scheduling.","solutions":["Call the merge endpoint (POST /~api/pull-requests/{requestId}/merge) directly instead of enabling auto-merge","Check merge eligibility first and branch: merge now if eligible, else enable auto-merge","Re-run the call only for PRs with an actual blocking condition","Fix automation logic to treat 'mergeable' as 'merge now'"],"exampleFix":"// before\npost('/~api/pull-requests/' + id + '/auto-merge', {enabled: true})\n// after\nvar pr = get('/~api/pull-requests/' + id)\nif (pr.mergeConditionSatisfied)\n  post('/~api/pull-requests/' + id + '/merge')\nelse\n  post('/~api/pull-requests/' + id + '/auto-merge', {enabled: true})","handlingStrategy":"validation","validationCode":"var pr = get('/~api/pull-requests/' + id)\nif (pr.mergeable === true) { // eligible to merge directly\n  post('/~api/pull-requests/' + id + '/merge');\n  return;\n}\npost('/~api/pull-requests/' + id + '/auto-merge', {enabled: true})","typeGuard":"function shouldAutoMerge(pr) { return !!pr && pr.status === 'OPEN' && pr.mergeable === false; }","tryCatchPattern":"try {\n  post('/~api/pull-requests/' + id + '/auto-merge', {enabled: true});\n} catch (e) {\n  if (e.status === 406 && /merged directly/i.test(e.body || '')) {\n    post('/~api/pull-requests/' + id + '/merge'); // merge now instead\n  } else throw e;\n}","preventionTips":["Check merge eligibility before enabling auto-merge and fall back to direct merge","Handle the race where the last blocking condition clears before your call","In automation, treat 'not eligible' as a hint to merge immediately","Only enable auto-merge for PRs with a known pending condition (failing build, pending review)"],"tags":["rest","pull-request","auto-merge","validation"],"backgroundTag":"invalid-state-transition","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"}