theonedev/onedev · error · ExplicitException

Pull request default assignee does not have code write permi

Error message

Pull request default assignee does not have code write permission over the target project: ${userName}

What it means

After resolving a pull request default assignee by name, OneDev verifies the user actually has code write permission on the target project (SecurityUtils.canWriteCode). This ExplicitException is thrown when the configured default assignee exists but lacks write access, since such a user could not accept/manage the pull request. Like the sibling 'not found' error it is a settings misconfiguration.

Source

Thrown at server-core/src/main/java/io/onedev/server/model/Project.java:2120

			if (current.getPullRequestSetting().getDeleteSourceBranchAfterMerge() != null)
				return current.getPullRequestSetting().getDeleteSourceBranchAfterMerge();
			current = current.getParent();
		} while (current != null);

		return false;
	}
	
	public List<User> findDefaultPullRequestAssignees() {
		Project current = this;
		do {
			if (!current.getPullRequestSetting().getDefaultAssignees().isEmpty()) {
				var users = new ArrayList<User>();
				for (var userName: current.getPullRequestSetting().getDefaultAssignees()) {
					var user = getUserService().findByName(userName);
					if (user == null)
						throw new ExplicitException("Pull request default assignee not found: " + userName);
					else if (!SecurityUtils.canWriteCode(user.asSubject(), this))
						throw new ExplicitException("Pull request default assignee does not have code write permission over the target project: " + userName);
					users.add(user);
				}
				return users;
			}
			current = current.getParent();
		} while (current != null);

		return new ArrayList<>();
	}
	
	public String getSiteLockName() {
		return getSiteLockName(getId());
	}
	
	public static String getSiteLockName(Long projectId) {
		return "project-site:" + projectId;
	}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Grant the default assignee code write permission on the target project (add to a group with Project Write/Code Write role)
  2. Or replace the default assignee in Pull Request settings with a user who already has write permission
  3. Check parent project settings if the project inherits its pull request configuration

Example fix

// before: assignee 'reader1' has only read access
// fix in project settings → Pull Request → Default Assignees
defaultAssignees: ["reader1"]
// after: use a maintainer
defaultAssignees: ["maintainer1"]
Defensive patterns

Strategy: validation

Validate before calling

for (String name : project.getPullRequestSetting().getDefaultAssignees()) {
    User u = OneDev.getInstance(UserService.class).findByName(name);
    if (u != null && !SecurityUtils.canWriteCode(u.asSubject(), project))
        throw new ValidationException("Assignee lacks write access: " + name);
}

Try / catch

try {
    users = project.getPullRequestSetting().getDefaultAssigneeUsers();
} catch (ExplicitException e) {
    logger.warn("Default assignee lacks write permission: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Opening a pull request whose target project (or an ancestor providing inherited settings) lists a default assignee that exists but only has read-level access to the target project.

Common situations: User role downgraded to read-only after being set as default assignee; assignee belongs to a group without project write access; settings inherited from a parent project where the permission check differs.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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