theonedev/onedev · error · UnauthorizedException

No permission to access report:

Error message

No permission to access report: 

What it means

GET /get-build-code-problems in TodResource throws UnauthorizedException ('No permission to access report: {name}') when SecurityUtils.canAccessReport(build, reportName) is false. The authenticated user can see the build but not this specific report, or lacks permission to the build's reports altogether.

Solutions

  1. Grant the user access to the report: adjust the report's authorization (job/report config) or the user's project role
  2. Publish the report without restrictive authorization if it should be visible to all project members
  3. Verify currentProject/reference/reportName resolve to the build and report you intend
  4. Use a token of a user with sufficient permissions on the project

Example fix

// before: CI job publishes report with authorization limited to Project Owners
// after: job yaml
publishReport: 'code-problems/**: !ReportAuthorization
  # or grant Developer role access to the report'
Defensive patterns

Strategy: validation

Validate before calling

const reports = await listBuildReports(buildId); if (!reports.some(r => r.name === reportName)) throw new Error(`Report '${reportName}' not accessible on build ${buildId}`);

Try / catch

try { await getBuildCodeProblems(params); } catch (e) { if (e.status === 403 || /no permission to access report/i.test(e.message)) escalatePermissions(reportName); else throw e; }

Prevention

When it happens

Trigger: Calling get-build-code-problems with a reportName the user has no report access to, e.g. reports published with restricted authorization, or the user has no permission on the project containing the build.

Common situations: AI agent using a low-privileged account; report published with a report authorization config limiting it to certain roles; accessing another project's build via reference; security setting changed after report publication.

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

Appendix: source

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

        var build = getBuild(currentProject, buildReference);
        return BuildHelper.getDetail(currentProject, build);
    }

    @Path("/get-build-code-problems")
    @GET
    public List<Map<String, Object>> getBuildCodeProblems(
                @QueryParam("currentProject") @NotNull String currentProjectPath, 
                @QueryParam("reference") @NotNull String buildReference, 
                @QueryParam("reportName") @NotNull String reportName, 
                @QueryParam("severityLevel") @NotNull CodeProblem.Severity severityLevel) {
        if (SecurityUtils.getUser() == null)
            throw new UnauthenticatedException();

        var currentProject = getProject(currentProjectPath);
        var build = getBuild(currentProject, buildReference);

        if (!SecurityUtils.canAccessReport(build, reportName))
            throw new UnauthorizedException("No permission to access report: " + reportName);

        var report = ProblemReport.readFrom(build, reportName);
        if (report == null)
            throw new NotFoundException("Code problem report not found: " + reportName);

        var problems = new ArrayList<Map<String, Object>>();
        for (var problem: report.getProblems()) {
            if (problem.getSeverity().ordinal() <= severityLevel.ordinal()) {
                var problemMap = new HashMap<String, Object>();
                problemMap.put("severity", problem.getSeverity().name());
                problemMap.put("message", problem.getMessage());
                if (problem.getTarget() instanceof BlobTarget blobTarget) {
                    problemMap.put("file", blobTarget.getGroupKey().getName());
                    if (blobTarget.getLocation() != null) {
                        problemMap.put("beginLine", blobTarget.getLocation().getFromRow() + 1);
                        problemMap.put("endLine", blobTarget.getLocation().getToRow() + 1);
                    }
                } else if (problem.getTarget() instanceof ContainerTarget containerTarget) {

View on GitHub (pinned to d44925c47c)