theonedev/onedev · error · UnauthorizedException
Code read permission required to query pull requests
Error message
Code read permission required to query pull requests
What it means
GET /query-pull-requests in TodResource throws UnauthorizedException when SecurityUtils.canReadCode(projectContext.project) is false. Querying pull requests requires code read permission on the project; the authenticated user lacks it.
Source
Thrown at server-core/src/main/java/io/onedev/server/ai/TodResource.java:800
return workMap;
}
@Path("/query-pull-requests")
@GET
public List<Map<String, Object>> queryPullRequests(
@QueryParam("currentProject") @NotNull String currentProjectPath,
@QueryParam("project") String projectPath,
@QueryParam("query") String query,
@QueryParam("offset") int offset,
@QueryParam("count") int count) {
var subject = SecurityUtils.getSubject();
if (SecurityUtils.getUser(subject) == null)
throw new UnauthenticatedException();
var projectContext = getProjectContext(projectPath, currentProjectPath);
if (!SecurityUtils.canReadCode(projectContext.project))
throw new UnauthorizedException("Code read permission required to query pull requests");
if (count > RestConstants.MAX_PAGE_SIZE)
throw new NotAcceptableException("Count should not be greater than " + RestConstants.MAX_PAGE_SIZE);
EntityQuery<PullRequest> parsedQuery;
if (query != null)
parsedQuery = PullRequestQuery.parse(projectContext.project, query, true);
else
parsedQuery = new PullRequestQuery();
var summaries = new ArrayList<Map<String, Object>>();
for (var pullRequest : pullRequestService.query(subject, projectContext.project, parsedQuery, false, offset, count)) {
var summary = PullRequestHelper.getSummary(projectContext.currentProject, pullRequest, false);
summary.put("link", urlService.urlFor(pullRequest, true));
summaries.add(summary);
}
return summaries;
}View on GitHub (pinned to d44925c47c)
Solutions
- Grant the user a project role with code read permission (Project > Access Control)
- Query pull requests only in projects the calling user can read code in
- Check the 'project'/'currentProject' query params resolve to the intended project
- Use a token of a user with at least Developer role in the target project
Example fix
// before: role 'Reader (issues only)' in project 'app' -> query-pull-requests fails // after: Project app > Access Control > change role to 'Developer' (code read included)
Defensive patterns
Strategy: validation
Validate before calling
const project = await getProject(projectPath ?? currentProject); if (!project.permissions?.canReadCode) throw new Error('Code read permission required to query pull requests on ' + projectPath); Try / catch
try { await queryPullRequests(params); } catch (e) { if (e.status === 403 || /code read permission/i.test(e.message)) useAccountWithCodeRead(); else throw e; } Prevention
- Give agent accounts at least code-read roles in target projects
- Resolve which project (project vs currentProject param) is queried and check its ACL
- Re-check permissions after project role changes
- Keep AI agent tokens scoped to users with needed project access
When it happens
Trigger: Calling query-pull-requests for a project where the user has no role granting code read (e.g. Issue Reporter-only role), or the resolved project (from 'project' or 'currentProject' param) is private to other users.
Common situations: AI agent running as a user with limited project roles; querying pull requests of another project passed via the 'project' query param; guest/anonymous-restricted accounts; project ACL changed recently.
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
- Access denied
- Issue schedule permission required to set own estimated time
- Issue schedule permission required to set iterations
- No permission to access issue: ${referenceString}
- No permission to write code in issue project
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/c7f84db6b9fa6a09.
Report an issue: GitHub.