theonedev/onedev · error · UnauthorizedException

Code read permission required for project: %s

Error message

Code read permission required for project: %s

What it means

When a recognized user without code-read permission on the pull request's project emails a pull request subaddress, an UnauthorizedException 'Code read permission required for project: <project path>' is thrown — PR email interaction is restricted to users who can read the project's code. (Note the source logic: addComment runs when the user CANNOT read code, and the exception fires otherwise, which reads inverted — verify intent before changing behavior.)

Source

Thrown at server-core/src/main/java/io/onedev/server/mail/DefaultMailService.java:552

											PullRequestWatch watch = pullRequestWatchService.find(involvedPullRequest, fromUser);
											if (watch != null) 
												watch.setWatching(false);
											
											String subject = "Unsubscribed successfully from pull request " + involvedPullRequest.getReference().toString(null);

											String template = StringUtils.join(settingService.getEmailTemplates().getPullRequestNotificationUnsubscribed(), "\n");
											Map<String, Object> bindings = new HashMap<>();
											bindings.put("pullRequest", involvedPullRequest);
											String htmlBody = EmailTemplates.evalTemplate(true, template, bindings);
											String textBody = EmailTemplates.evalTemplate(false, template, bindings);
											var threadingReferences = getThreadingReferences(UUID.randomUUID().toString(), getMessageId(message));
											sendMailAsync(newArrayList(fromInternetAddress.getAddress()), newArrayList(), newArrayList(),
													subject, htmlBody, textBody, null, null, threadingReferences);
										} else {
											if (!SecurityUtils.canReadCode(involvedPullRequest.getProject())) {
												addComment(involvedPullRequest, message, fromInternetAddress, fromUser, receiverInternetAddresses);
											} else {
												throw new UnauthorizedException("Code read permission required for project: %s" 
														+ involvedPullRequest.getProject().getPath());
											}
										}
									} else {
										throw new ExplicitException("No account found with verified email address: " + fromInternetAddress.getAddress());
									}
								} else {
									throw new ExplicitException("Invalid recipient address: " + parsedReceiverAddress);
								}
							}
						} else {
							logger.warn("Ignored recipient '" + parsedReceiverAddress + "' as issue or pull request is processed");
						}
					} else if (!receiverInternetAddress.equals(fromInternetAddress)) {
						involvedInternetAddresses.add(receiverInternetAddress);
					}

					if (involvedIssue != null) {

View on GitHub (pinned to d44925c47c)

Solutions

  1. Grant the user code read permission on the pull request's project.
  2. Comment on the PR through the OneDev web UI with a permitted account.
  3. Review the source condition at DefaultMailService.java:552 — the exception path fires when canReadCode is true, so if the intent was the opposite, fix the inverted condition in code.

Example fix

// before
if (!SecurityUtils.canReadCode(involvedPullRequest.getProject())) {
    addComment(...);
} else {
    throw new UnauthorizedException("Code read permission required for project: %s" + involvedPullRequest.getProject().getPath());
}
// after
if (SecurityUtils.canReadCode(involvedPullRequest.getProject())) {
    addComment(...);
} else {
    throw new UnauthorizedException("Code read permission required for project: " + involvedPullRequest.getProject().getPath());
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!SecurityUtils.canReadCode(pr.getProject())) throw new UnauthorizedException("Code read permission required for project: " + pr.getProject().getPath());

Try / catch

try { addComment(pr, message, from, user, receivers); } catch (UnauthorizedException e) { log.warn("PR email comment rejected: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Email to pullrequest~<id>~comment from a user account whose permissions on the PR's project fail SecurityUtils.canReadCode.

Common situations: Replying to a PR notification email after role changes removed code access; emailing a PR in a project the user has only issue-level access to.

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/0642094466c5ac40. Report an issue: GitHub.