theonedev/onedev · error · NotAcceptableException

Pull request does not belong to specified project

Error message

Pull request does not belong to specified project

What it means

OneDev throws this 406 NotAcceptableException when the referenced pull request exists but belongs to a project different from the project specified in the workspace creation request. Workspaces may only link pull requests from the same project.

Source

Thrown at server-core/src/main/java/io/onedev/server/rest/resource/WorkspaceResource.java:135

		if (commit == null) 
			throw new NotAcceptableException("Commit not found: " + data.getCommitHash());

		Issue issue = null;
		if (data.getIssueId() != null) {
			issue = issueService.get(data.getIssueId());
			if (issue == null)
				throw new NotAcceptableException("Issue not found by id: " + data.getIssueId());
			if (!issue.getProject().equals(project))
				throw new NotAcceptableException("Issue does not belong to specified project");
		}

		PullRequest request = null;
		if (data.getPullRequestId() != null) {
			request = pullRequestService.get(data.getPullRequestId());
			if (request == null)
				throw new NotAcceptableException("Pull request not found by id: " + data.getPullRequestId());
			if (!request.getProject().equals(project))
				throw new NotAcceptableException("Pull request does not belong to specified project");
		}

		Workspace workspace = workspaceService.create(user, project, issue, request, commitId,
				data.getBranch(), data.getSpecName(), false);
		return workspace.getId();
	}

	@Api(order=400, description="Reprovision inactive workspace")
	@Path("/{workspaceId}/reprovision")
	@POST
	public Response reprovisionWorkspace(@PathParam("workspaceId") Long workspaceId) {
		Workspace workspace = workspaceService.load(workspaceId);
		if (!SecurityUtils.canModifyOrDelete(workspace))
			throw new UnauthorizedException();
		if (workspace.getStatus() != Status.INACTIVE)
			throw new NotAcceptableException("Only inactive workspaces can be reprovisioned");
		workspaceService.reset(workspace);
		return Response.ok().build();

View on GitHub (pinned to d44925c47c)

Solutions

  1. Check request.getProject() equals the PR's target project before calling; use a PR belonging to the specified project.
  2. Change the request's projectId to the project the PR belongs to.
  3. Omit pullRequestId if the linkage is optional for the workflow.

Example fix

// before
PullRequest pr = pullRequestService.get(data.getPullRequestId());
workspaceService.create(user, fork, issue, pr, ...);
// after
PullRequest pr = pullRequestService.get(data.getPullRequestId());
if (pr != null && pr.getProject().equals(project)) {
    workspaceService.create(user, project, issue, pr, ...);
}
Defensive patterns

Strategy: validation

Validate before calling

PullRequest pr = pullRequestService.get(data.getPullRequestId());
if (pr != null && !pr.getProject().equals(project))
    throw new IllegalArgumentException("PR #" + pr.getNumber() + " belongs to " + pr.getProject().getPath());

Type guard

boolean pullRequestInProject(PullRequest pr, Project project) {
    return pr != null && pr.getProject().equals(project);
}

Prevention

When it happens

Trigger: POSTing to the workspace REST resource with project=X but pullRequestId referencing a PR in project Y (including PRs on forks whose target is a different project).

Common situations: Cross-repo automation pipelines passing a PR id from an upstream project; users confusing a fork's PR with the target project's PR; batch scripts that look up PRs globally.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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