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
- Grant the user code read permission on the pull request's project.
- Comment on the PR through the OneDev web UI with a permitted account.
- 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
- Ensure code read permission before emailing PRs
- Review the possibly-inverted condition at DefaultMailService.java:552
- Prefer web UI for PR discussions when access is uncertain
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
- No permission to read code of source project:
- No permission to read code of target project:
- No permission to access pull request:
- No permission to edit pull request:
- No permission to comment issue:
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/0642094466c5ac40.
Report an issue: GitHub.