theonedev/onedev · error · UnauthorizedException

No permission to access issue: ${referenceString}

Error message

No permission to access issue: ${referenceString}

What it means

getIssue throws UnauthorizedException when the referenced issue exists but the current user lacks permission to see it (SecurityUtils.canAccessIssue returns false). This prevents the AI tool endpoints from leaking issue data to unauthorized users. It is distinct from not-found: the issue is there, access is denied.

Source

Thrown at server-core/src/main/java/io/onedev/server/ai/TodResource.java:466

        var summaries = new ArrayList<Map<String, Object>>();
        for (var issue : issueService.query(subject, new ProjectScope(projectContext.project, true, false), parsedQuery, true, offset, count)) {
            var summary = IssueHelper.getSummary(projectContext.currentProject, issue);
            for (var entry: issue.getFieldInputs().entrySet()) {
                summary.put(entry.getKey(), entry.getValue().getValues());
            }
            summary.put("link", urlService.urlFor(issue, true));
            summaries.add(summary);
        }
        return summaries;
    }

    private Issue getIssue(Project currentProject, String referenceString) {
        var issueReference = IssueReference.of(referenceString, currentProject);
        var issue = issueService.find(issueReference.getProject(), issueReference.getNumber());
        if (issue != null) {
            if (!SecurityUtils.canAccessIssue(issue))
                throw new UnauthorizedException("No permission to access issue: " + referenceString);
            return issue;
        } else {
            throw new NotFoundException("Issue not found: " + referenceString);
        }
    }
    
    @Path("/get-issue")
    @GET
    public Map<String, Object> getIssueDetail(
                @QueryParam("currentProject") @NotNull String currentProjectPath, 
                @QueryParam("reference") @NotNull String issueReference, 
                @QueryParam("forWrite") Boolean forWrite) {
        var subject = SecurityUtils.getSubject();
        if (SecurityUtils.getUser(subject) == null)
            throw new UnauthenticatedException();

        var currentProject = getProject(currentProjectPath);
        var issue = getIssue(currentProject, issueReference);                

View on GitHub (pinned to d44925c47c)

Solutions

  1. Log in as a user with at least read access to the issue's project, or ask an admin to grant the role.
  2. Use an access token belonging to a member of the target project.
  3. Verify project authorization/privacy settings in OneDev admin if access should be allowed.
  4. If the reference may point at an arbitrary project, first check the user can access that project before calling.

Example fix

// before (client)
const issue = getIssue(currentProject, "other-private-project#12")
// after
if (!canUserAccessProject(user, "other-private-project")) {
  throw new Error("Requesting user lacks access to other-private-project#12")
}
const issue = getIssue(currentProject, "other-private-project#12")
Defensive patterns

Strategy: validation

Validate before calling

// pre-check the user can access the project containing the issue
const project = await getProject(refProjectPath);
if (!project || !userCanAccess(project, currentUser))
  throw new Error(`No access to project ${refProjectPath} for issue ${ref}`);

Try / catch

try {
  return await getIssue(ref);
} catch (e) {
  if (isUnauthorizedError(e)) {
    notifyUserOfMissingPermission(ref);
    return null; // degrade gracefully
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling issue/sourceIssue/targetIssue (e.g. via get-issue or get-issue-comments) with a reference string resolving to an existing issue in a project the authenticated user cannot access (private project, restricted role, or confidential issue).

Common situations: A service account token with insufficient project roles; user references an issue from another team's private project; project confidentiality settings exclude the user from the issue.

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