theonedev/onedev · warning · 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
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.
Source
Thrown at server-core/src/main/java/io/onedev/server/rest/resource/PullRequestResource.java:509
throw new NotAcceptableException("Pull request is closed");
pullRequestChangeService.changeMergeStrategy(user, request, mergeStrategy);
return Response.ok().build();
}
@Api(order=1550)
@Path("/{requestId}/auto-merge")
@POST
public Response setAutoMerge(@PathParam("requestId") Long requestId, @NotNull AutoMergeData data) {
var subject = SecurityUtils.getSubject();
var user = SecurityUtils.getUser(subject);
PullRequest request = pullRequestService.load(requestId);
if (!SecurityUtils.canModifyPullRequest(subject, request) || !SecurityUtils.canWriteCode(subject, request.getProject()))
throw new UnauthorizedException();
if (!request.isOpen())
throw new NotAcceptableException("Pull request is closed");
if (data.isEnabled() && 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(data.isEnabled());
autoMerge.setCommitMessage(data.getCommitMessage());
var errorMessage = request.checkMergeCommitMessage(user, autoMerge.getCommitMessage());
if (errorMessage != null)
throw new NotAcceptableException("Error validating auto merge commit message: " + errorMessage);
pullRequestChangeService.changeAutoMerge(user, request, autoMerge);
return Response.ok().build();
}
@Api(order=1600)
@Path("/{requestId}/reopen")
@POST
public Response reopenPullRequest(@PathParam("requestId") Long requestId, String note) {
PullRequest request = pullRequestService.load(requestId);View on GitHub (pinned to d44925c47c)
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'
Example fix
// before
post('/~api/pull-requests/' + id + '/auto-merge', {enabled: true})
// after
var pr = get('/~api/pull-requests/' + id)
if (pr.mergeConditionSatisfied)
post('/~api/pull-requests/' + id + '/merge')
else
post('/~api/pull-requests/' + id + '/auto-merge', {enabled: true}) Defensive patterns
Strategy: validation
Validate before calling
var pr = get('/~api/pull-requests/' + id)
if (pr.mergeable === true) { // eligible to merge directly
post('/~api/pull-requests/' + id + '/merge');
return;
}
post('/~api/pull-requests/' + id + '/auto-merge', {enabled: true}) Type guard
function shouldAutoMerge(pr) { return !!pr && pr.status === 'OPEN' && pr.mergeable === false; } Try / catch
try {
post('/~api/pull-requests/' + id + '/auto-merge', {enabled: true});
} catch (e) {
if (e.status === 406 && /merged directly/i.test(e.body || '')) {
post('/~api/pull-requests/' + id + '/merge'); // merge now instead
} else throw e;
} Prevention
- 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)
When it happens
Trigger: 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.
Common situations: 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.
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
- Error validating param auto merge commit message:
- Error validating auto merge commit message:
- Count should not be greater than ${RestConstants.MAX_PAGE_SI
- Count should not be greater than
- Pull request submitter cannot be reviewer
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/955f82a1a54ff82e.
Report an issue: GitHub.