theonedev/onedev · error · NotAcceptableException

Pull request is closed

Error message

Pull request is closed

What it means

NotAcceptableException (HTTP 400) thrown from POST /pull-requests/{requestId}/merge-strategy when the pull request is no longer open (request.isOpen() is false). A merge strategy can only be configured on open pull requests; closed, merged, or discarded requests reject the change.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/PullRequestResource.java:491

				.findFirst()
				.orElse(null);
		if (assignment != null)
			pullRequestAssignmentService.delete(assignment);

		return Response.ok().build();
	}
	
	@Api(order=1500)
	@Path("/{requestId}/merge-strategy")
    @POST
    public Response setMergeStrategy(@PathParam("requestId") Long requestId, @NotNull MergeStrategy mergeStrategy) {
		PullRequest request = pullRequestService.load(requestId);
		var subject = SecurityUtils.getSubject();
		var user = SecurityUtils.getUser(subject);
    	if (!SecurityUtils.canModifyPullRequest(subject, request))
			throw new UnauthorizedException();
		if (!request.isOpen())
			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");

View on GitHub (pinned to d44925c47c)

Solutions

  1. Re-fetch the pull request state and confirm it is open before calling the endpoint.
  2. If the PR is merged, there is nothing to configure — operate on the next open PR.
  3. Reopen the discarded PR (if possible) before setting the merge strategy, or skip closed PRs in batch scripts by filtering on status=open.

Example fix

// before
requests.post(f"{url}/api/pull-requests/{pr_id}/merge-strategy", data="SQUASH_ALL_COMMITS")
// after
pr = get_pull_request(pr_id)
if pr["status"] == "OPEN":
    requests.post(f"{url}/api/pull-requests/{pr_id}/merge-strategy", data="SQUASH_ALL_COMMITS")
Defensive patterns

Strategy: validation

Validate before calling

const pr = await api.getPullRequest(requestId);
if (pr.status !== "OPEN") throw new Error(`Pull request ${requestId} is ${pr.status}; merge strategy can only be set on open PRs`);

Try / catch

try {
  await api.setMergeStrategy(requestId, strategy);
} catch (e) {
  if (e.status === 400 && /closed/.test(e.body)) {
    // refresh PR state; skip or reopen
  } else throw e;
}

Prevention

When it happens

Trigger: Calling setMergeStrategy on a PR that was already merged, discarded/closed, or closed automatically (e.g. by branch deletion or target commit pushed), after another thread closed it.

Common situations: Automation races: script fetched PR list, PR got merged before the strategy update; UI stale tab submits on a closed PR; branch was deleted causing auto-close.

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/a6c5401bb4112f63. Report an issue: GitHub.