theonedev/onedev · info · NotAcceptableException
Another pull request already merged the change
Error message
Another pull request already merged the change
What it means
DefaultPullRequestService.open() throws this when findEffective(target, source) returns a PR that is not open — meaning the same source->target change was already merged (or otherwise closed as effective). Creating a new PR would be pointless because the target already contains the change.
Source
Thrown at server-core/src/main/java/io/onedev/server/service/impl/DefaultPullRequestService.java:447
"Pull request target must be set before calling open");
var source = Preconditions.checkNotNull(request.getSource(),
"Pull request source must be set before calling open");
Preconditions.checkNotNull(request.getSubmitter(),
"Pull request submitter must be set before calling open");
if (target.equals(source))
throw new NotAcceptableException("Source and target are the same");
PullRequest existing = findOpen(target, source);
if (existing != null)
throw new NotAcceptableException("Another pull request already opened for this change");
existing = findEffective(target, source);
if (existing != null) {
if (existing.isOpen())
throw new NotAcceptableException("Another pull request already opened for this change");
else
throw new NotAcceptableException("Another pull request already merged the change");
}
if (request.getBaseCommitHash() == null) {
ObjectId baseCommitId = gitService.getMergeBase(
target.getProject(), target.getObjectId(),
source.getProject(), source.getObjectId());
if (baseCommitId == null)
throw new NotAcceptableException("No common base for target and source");
request.setBaseCommitHash(baseCommitId.name());
}
if (request.getBaseCommitHash().equals(source.getObjectName()))
throw new NotAcceptableException("Target already up to date with source");
if (request.getUpdates().isEmpty()) {
PullRequestUpdate update = new PullRequestUpdate();
request.getUpdates().add(update);
request.setUpdates(request.getUpdates());View on GitHub (pinned to d44925c47c)
Solutions
- Check the existing effective PR and inform the user the change was already merged (link to it)
- Fast-forward/delete the source branch or sync it with target so it no longer differs
- Skip PR creation in automation when findEffective returns a merged PR
- If a partial change remains, push new commits and a new branch before opening a PR
Example fix
// before
pullRequestService.open(request);
// after
PullRequest effective = pullRequestService.findEffective(target, source);
if (effective != null && !effective.isOpen())
throw new SkipException("Change already merged in PR #" + effective.getNumber());
pullRequestService.open(request); Defensive patterns
Strategy: validation
Validate before calling
PullRequest effective = pullRequestService.findEffective(target, source);
if (effective != null && !effective.isOpen())
throw new SkipException("Already merged: PR #" + effective.getNumber()); Try / catch
try {
pullRequestService.open(request);
} catch (NotAcceptableException e) {
if (e.getMessage().contains("already merged the change"))
logger.info("Skipping: change already merged");
else throw e;
} Prevention
- Delete or archive source branches after merge so automation stops trying
- Check findEffective before opening PRs from long-lived automation branches
- Skip zero-diff branches before calling open()
When it happens
Trigger: Calling open() for a source branch whose changes were already merged into the target via a prior pull request (findEffective returns a closed/merged PR).
Common situations: CI auto-creating PRs from long-lived branches after the change was merged; user rebases a merged branch and retries; backport scripts re-opening PRs for already-merged commits.
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
- Reviewer not found:
- Pull request submitter cannot be reviewer
- Assignee not found:
- No permission to read code of source project:
- No permission to read code of target project:
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/fbd50ca4e206a8d0.
Report an issue: GitHub.