theonedev/onedev · error · NotAcceptableException

This pull request is not eligible for auto-merge, as it can

Error message

This pull request is not eligible for auto-merge, as it can be merged directly now

What it means

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.

Source

Thrown at server-core/src/main/java/io/onedev/server/ai/TodResource.java:1437

            var requiredReviewers = excludedReviews.stream()
                    .filter(it -> it.getStatus() != PullRequestReview.Status.EXCLUDED)
                    .map(it -> it.getUser().getName())
                    .collect(Collectors.toList());
            if (!requiredReviewers.isEmpty())
                throw new NotAcceptableException("Unable to remove mandatory reviewers: " + String.join(", ", requiredReviewers));
            for (var review : excludedReviews) 
                pullRequestReviewService.createOrUpdate(user, review);
        }

        var autoMergeEnabled = (Boolean) data.remove("autoMerge");
        if (autoMergeEnabled != null) {
            if (!SecurityUtils.canWriteCode(request.getProject()))
                throw new UnauthorizedException("Code write permission is required to edit auto merge");
            if (!request.isOpen())
                throw new NotAcceptableException("Pull request is closed");

            if (autoMergeEnabled && request.checkMergeCondition() == null) 
                throw new NotAcceptableException("This pull request is not eligible for auto-merge, as it can be merged directly now");

            var autoMerge = new AutoMerge();
            autoMerge.setEnabled(autoMergeEnabled);
            autoMerge.setCommitMessage(trimToNull((String) data.remove("autoMergeCommitMessage")));
            var errorMessage = request.checkMergeCommitMessage(user, autoMerge.getCommitMessage());
            if (errorMessage != null) 
                throw new NotAcceptableException("Error validating param auto merge commit message: " + errorMessage);

            pullRequestChangeService.changeAutoMerge(user, request, autoMerge);
        }
                    
        return PullRequestHelper.getDetail(currentProject, request);        
    }    

    @Path("/approve-pull-request")
    @Consumes(MediaType.TEXT_PLAIN)
    @POST
    public Map<String, Object> approvePullRequest(

View on GitHub (pinned to d44925c47c)

Solutions

  1. Call mergePullRequest directly instead of enabling auto-merge when the PR is already mergeable.
  2. Check the merge condition first and branch: eligible => merge, not eligible => enable auto-merge.
  3. If the intent is to keep auto-merge armed for future changes, wait until a blocking condition exists.

Example fix

// before
updatePullRequest(ref, { autoMerge: true })
// after
const pr = getPullRequest(ref)
if (pr.mergeable) mergePullRequest(ref)
else updatePullRequest(ref, { autoMerge: true })
Defensive patterns

Strategy: validation

Validate before calling

const pr = await getPullRequest(ref)
if (pr.state === 'OPEN' && pr.mergeable) await mergePullRequest(ref)
else await updatePullRequest(ref, { autoMerge: true })

Type guard

function canArmAutoMerge(pr) { return pr && pr.state === 'OPEN' && !pr.mergeable }

Try / catch

try { await updatePullRequest(ref, { autoMerge: true }) }
catch (e) { if (String(e.message).includes('not eligible for auto-merge')) { await mergePullRequest(ref) } else throw e }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/c68d6dfce1253d7e. Report an issue: GitHub.