{"record":{"id":"c68d6dfce1253d7e","repo":"theonedev/onedev","slug":"this-pull-request-is-not-eligible-for-auto-merge","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":"error","filePath":"server-core/src/main/java/io/onedev/server/ai/TodResource.java","lineNumber":1437,"sourceCode":"            var requiredReviewers = excludedReviews.stream()\n                    .filter(it -> it.getStatus() != PullRequestReview.Status.EXCLUDED)\n                    .map(it -> it.getUser().getName())\n                    .collect(Collectors.toList());\n            if (!requiredReviewers.isEmpty())\n                throw new NotAcceptableException(\"Unable to remove mandatory reviewers: \" + String.join(\", \", requiredReviewers));\n            for (var review : excludedReviews) \n                pullRequestReviewService.createOrUpdate(user, review);\n        }\n\n        var autoMergeEnabled = (Boolean) data.remove(\"autoMerge\");\n        if (autoMergeEnabled != null) {\n            if (!SecurityUtils.canWriteCode(request.getProject()))\n                throw new UnauthorizedException(\"Code write permission is required to edit auto merge\");\n            if (!request.isOpen())\n                throw new NotAcceptableException(\"Pull request is closed\");\n\n            if (autoMergeEnabled && request.checkMergeCondition() == null) \n                throw new NotAcceptableException(\"This pull request is not eligible for auto-merge, as it can be merged directly now\");\n\n            var autoMerge = new AutoMerge();\n            autoMerge.setEnabled(autoMergeEnabled);\n            autoMerge.setCommitMessage(trimToNull((String) data.remove(\"autoMergeCommitMessage\")));\n            var errorMessage = request.checkMergeCommitMessage(user, autoMerge.getCommitMessage());\n            if (errorMessage != null) \n                throw new NotAcceptableException(\"Error validating param auto merge commit message: \" + errorMessage);\n\n            pullRequestChangeService.changeAutoMerge(user, request, autoMerge);\n        }\n                    \n        return PullRequestHelper.getDetail(currentProject, request);        \n    }    \n\n    @Path(\"/approve-pull-request\")\n    @Consumes(MediaType.TEXT_PLAIN)\n    @POST\n    public Map<String, Object> approvePullRequest(","sourceCodeStart":1419,"sourceCodeEnd":1455,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/ai/TodResource.java#L1419-L1455","documentation":"OneDev throws this NotAcceptableException when auto-merge is requested for a pull request whose merge condition is already satisfied (request.checkMergeCondition() returns null), meaning the PR can be merged directly and auto-merge is pointless/redundant.","triggerScenarios":"Calling the update-pull-request endpoint with autoMerge=true on an open PR that currently has no failed checks, no required reviews pending, and no conflicts — checkMergeCondition() returns null because nothing blocks a direct merge.","commonSituations":"CI is green and all reviews approved, so the automation tries to 'enable auto-merge' but the PR is mergeable right now; branch protection was relaxed so the condition that previously blocked merge disappeared.","solutions":["Call mergePullRequest directly instead of enabling auto-merge when the PR is already mergeable.","Check the merge condition first and branch: eligible => merge, not eligible => enable auto-merge.","If the intent is to keep auto-merge armed for future changes, wait until a blocking condition exists."],"exampleFix":"// before\nupdatePullRequest(ref, { autoMerge: true })\n// after\nconst pr = getPullRequest(ref)\nif (pr.mergeable) mergePullRequest(ref)\nelse updatePullRequest(ref, { autoMerge: true })","handlingStrategy":"validation","validationCode":"const pr = await getPullRequest(ref)\nif (pr.state === 'OPEN' && pr.mergeable) await mergePullRequest(ref)\nelse await updatePullRequest(ref, { autoMerge: true })","typeGuard":"function canArmAutoMerge(pr) { return pr && pr.state === 'OPEN' && !pr.mergeable }","tryCatchPattern":"try { await updatePullRequest(ref, { autoMerge: true }) }\ncatch (e) { if (String(e.message).includes('not eligible for auto-merge')) { await mergePullRequest(ref) } else throw e }","preventionTips":["Check mergeability before enabling auto-merge","When all checks/reviews pass, call merge directly","Treat 'auto-merge rejected because mergeable' as success — the goal (merge) is achievable now"],"tags":["pull-request","auto-merge","merge-condition"],"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-14T05:17:10.506Z"}