theonedev/onedev · error · NotAcceptableException

Assignee needs to have write code permission to the project

Error message

Assignee needs to have write code permission to the project

What it means

NotAcceptableException (HTTP 400) thrown when the user being assigned lacks write-code permission on the pull request's target project. An assignee is expected to work on the code, so OneDev refuses users without at least Developer/Writer access. This validates the nominated user's permissions, not the caller's.

Source

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

				throw new NotAcceptableException("This reviewer is mandatory and cannot be removed");
			pullRequestReviewService.createOrUpdate(user, review);
		}

		return Response.ok().build();	
	}

	@Api(order=1480)
	@Path("/{requestId}/assignees/{userId}")
	@POST
	public Response addAssignee(@PathParam("requestId") Long requestId, @PathParam("userId") Long userId) {
		var request = pullRequestService.load(requestId);
		var user = userService.load(userId);

		if (!SecurityUtils.canModifyPullRequest(request))
			throw new UnauthorizedException();

		if (!SecurityUtils.canWriteCode(user.asSubject(), request.getProject()))
			throw new NotAcceptableException("Assignee needs to have write code permission to the project");

		if (request.getAssignees().contains(user))
			return Response.ok().build();

		var assignment = new PullRequestAssignment();
		assignment.setRequest(request);
		assignment.setUser(user);
		pullRequestAssignmentService.create(assignment);

		return Response.ok().build();
	}

	@Api(order=1490)
	@Path("/{requestId}/assignees/{userId}")
	@DELETE
	public Response removeAssignee(@PathParam("requestId") Long requestId, @PathParam("userId") Long userId) {
		var request = pullRequestService.load(requestId);
		var user = userService.load(userId);

View on GitHub (pinned to d44925c47c)

Solutions

  1. Grant the nominated user write-code (Developer) permission on the target project, then retry.
  2. Assign a user who already has write access.
  3. Reassign via a group that carries Developer role on the project.

Example fix

// before
POST .../pull-requests/42/assignees/107 -> 400 Assignee needs write code permission
// after: grant user 107 Developer role on the project, then
POST .../pull-requests/42/assignees/107 -> 200 OK
Defensive patterns

Strategy: validation

Validate before calling

const canWrite = await onedevApi.projectQueryPermission(projectId, "WRITE_CODE", candidateUserId);
if (!canWrite) throw new Error(`User ${candidateUserId} lacks WRITE_CODE on project ${projectId}; grant Developer role first`);

Try / catch

try {
  await api.addAssignee(requestId, userId);
} catch (e) {
  if (e.status === 400 && /write code permission/.test(e.body)) {
    // grant Developer role or select a different assignee
  } else throw e;
}

Prevention

When it happens

Trigger: POST .../assignees/{userId} where SecurityUtils.canWriteCode(user.asSubject(), request.getProject()) is false — the nominated user has no write (Developer+) role on the target project.

Common situations: Assigning a QA or read-only stakeholder; user belongs to another project; project roles changed so the user lost Developer access; scripts assign arbitrary user IDs.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


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