theonedev/onedev · error · UnauthorizedException
No permission to comment issue:
Error message
No permission to comment issue:
What it means
When replying by email to an issue subaddress, if the sender maps to a known OneDev user lacking access to the issue (SecurityUtils.canAccessIssue fails), an UnauthorizedException 'No permission to comment issue: <ref>' is thrown instead of adding the comment.
Source
Thrown at server-core/src/main/java/io/onedev/server/mail/DefaultMailService.java:520
}
String subject = "Unsubscribed successfully from issue " + involvedIssue.getReference();
String template = settingService.getEmailTemplates().getIssueNotificationUnsubscribed();
Map<String, Object> bindings = new HashMap<>();
bindings.put("issue", involvedIssue);
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 (fromUser != null) {
if (SecurityUtils.canAccessIssue(fromUser.asSubject(), involvedIssue))
addComment(involvedIssue, message, fromInternetAddress, fromUser, receiverInternetAddresses);
else
throw new UnauthorizedException("No permission to comment issue: " + involvedIssue.getReference());
} else {
if (involvedIssue.getExternalParticipants().contains(fromInternetAddress))
addComment(involvedIssue, message, fromInternetAddress, null, receiverInternetAddresses);
else
throw new UnauthorizedException("Not eligible to comment issue: " + involvedIssue.getReference());
}
}
} else if (subAddress.contains("pullrequest")) {
if (fromUser != null) {
involvedPullRequest = pullRequestService.get(entityId);
if (involvedPullRequest == null)
throw new ExplicitException("Non-existent pull request specified in recipient address: " + parsedReceiverAddress);
if (subAddress.contains("unsubscribe")) {
PullRequestWatch watch = pullRequestWatchService.find(involvedPullRequest, fromUser);
if (watch != null)
watch.setWatching(false);
String subject = "Unsubscribed successfully from pull request " + involvedPullRequest.getReference().toString(null);View on GitHub (pinned to d44925c47c)
Solutions
- Grant the user read access to the issue's project (appropriate role/permissions).
- Comment via the OneDev web UI with an account that has access.
- If the user should not have access, stop emailing that issue address.
Example fix
// admin: grant access // before: user has no role on project 'app' // after: assign role with 'Read Issue' permission to the user on project 'app'
Defensive patterns
Strategy: try-catch
Validate before calling
if (!SecurityUtils.canAccessIssue(user.asSubject(), issue)) throw new UnauthorizedException("No permission to comment issue: " + issue.getReference()); Try / catch
try { addComment(issue, message, from, user, receivers); } catch (UnauthorizedException e) { log.warn("Email comment rejected: {}", e.getMessage()); } Prevention
- Only reply from accounts with project access
- Check user roles after permission changes
- Use web UI when unsure of access
When it happens
Trigger: Email reply to issue~<id>~comment from a recognized user account whose permissions do not allow reading the issue.
Common situations: User's access to the project/issue was revoked after subscribing; reply from a coworker's account without project access; group/role changes restricting confidential issues.
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
- Code read permission required for project: %s
- Access denied
- Issue schedule permission required to set own estimated time
- Issue schedule permission required to set iterations
- No permission to access issue: ${referenceString}
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/ad3ff13ed33dd7b9.
Report an issue: GitHub.