theonedev/onedev · info · NotAcceptableException

Target already up to date with source

Error message

Target already up to date with source

What it means

DefaultPullRequestService.open() rejects the request when the computed base commit equals the source branch's current head (getObjectName()), meaning the target already contains everything on source — there is nothing to merge, so a PR would be empty.

Source

Thrown at server-core/src/main/java/io/onedev/server/service/impl/DefaultPullRequestService.java:460

		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());
			update.setRequest(request);
			update.setHeadCommitHash(source.getObjectName());
			update.setTargetHeadCommitHash(target.getObjectName());
		}

		if (request.getAssignments().isEmpty()) {
			for (var assignee: target.getProject().findDefaultPullRequestAssignees()) {
				PullRequestAssignment assignment = new PullRequestAssignment();
				assignment.setRequest(request);
				assignment.setUser(assignee);
				request.getAssignments().add(assignment);
			}
		}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Verify there are unmerged commits: the source head must differ from the target tip; push new commits first
  2. Pull/rebase source on top of target to add new work, then open the PR
  3. If the work is already merged, skip PR creation and close the task
  4. Check your automation isn't opening PRs against the wrong (already-synced) target branch

Example fix

// before
if (target.getObjectId().equals(source.getObjectId())) skip; // wrong check
pullRequestService.open(request);
// after
if (request.getBaseCommitHash().equals(source.getObjectName())) {
    logger.info("No changes from {} to {}", source, target);
    return;
}
pullRequestService.open(request);
Defensive patterns

Strategy: validation

Validate before calling

if (request.getBaseCommitHash().equals(source.getObjectName()))
    return; // target already up to date, nothing to merge

Try / catch

try {
    pullRequestService.open(request);
} catch (NotAcceptableException e) {
    if (e.getMessage().contains("Target already up to date"))
        logger.info("Nothing to merge; skipping PR creation");
    else throw e;
}

Prevention

When it happens

Trigger: Calling open() when request.getBaseCommitHash().equals(source.getObjectName()): target is already at or ahead of the source head, i.e. zero diff between merge base and source tip.

Common situations: Opening a PR from a branch that was already fast-forward-merged; target branch was reset to the source head; automation opening PRs after a merge bot already fast-forwarded; comparing a branch with itself after rebase onto target.

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