theonedev/onedev · error · org.apache.shiro.authz.UnauthorizedException

No permission to access build: ${referenceString}

Error message

No permission to access build: ${referenceString}

What it means

getBuild resolves a build reference (like '#123' or 'project/#123') and then checks SecurityUtils.canAccessProject on the build's project. If the build exists but the current user lacks access to that project, UnauthorizedException is thrown with the reference string embedded.

Source

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

            }
            if (validationErrors.isEmpty()) {
                return Response.ok(VersionedYamlDoc.fromBean(buildSpec).toYaml()).build();
            } else {
                return Response.status(NOT_ACCEPTABLE).entity(Joiner.on("\n").join(validationErrors) + schemaNotice).build();
            }
        } catch (Exception e) {
            return Response.status(NOT_ACCEPTABLE).entity(Throwables.getStackTraceAsString(e) + schemaNotice).build();
		} finally {
			Project.pop();
		}
    }

    private Build getBuild(Project currentProject, String referenceString) {
        var buildReference = BuildReference.of(referenceString, currentProject);
        var build = buildService.find(buildReference.getProject(), buildReference.getNumber());
        if (build != null) {
            if (!SecurityUtils.canAccessProject(build.getProject()))
                throw new UnauthorizedException("No permission to access build: " + referenceString);
            return build;
        } else {
            throw new NotFoundException("Build not found: " + referenceString);
        }
    }
    
    private void normalizePullRequestData(Map<String, Serializable> data) {
        for (var entry : data.entrySet()) {
            if (entry.getValue() instanceof String)
                entry.setValue(trimToNull((String) entry.getValue()));
        }
    }    

    private static class ProjectContext {
        
        Project project;

        Project currentProject;

View on GitHub (pinned to d44925c47c)

Solutions

  1. Ask an administrator to grant the user appropriate access to the referenced build's project.
  2. Use a build reference within a project the current user can access.
  3. Check the user's project permissions in OneDev administration (Project -> Members/Roles) before retrying.

Example fix

// before
Build b = getBuild(currentProject, "other-secret-project/#42"); // user has no access
// after
Build b = getBuild(currentProject, currentProject.getPath() + "/#42"); // accessible project
Defensive patterns

Strategy: try-catch

Validate before calling

// only reference builds in projects the user can access
const accessible = await listAccessibleProjects(user);
if (!accessible.includes(refProject)) throw new Error("No permission to access project of build " + ref);

Try / catch

try { return getBuild(ref); } catch (e) { if (/No permission to access build/.test(e.message)) { notifyUser("Request access to the build's project first"); } throw e; }

Prevention

When it happens

Trigger: Calling any TodResource tool that takes a build reference where the referenced build's project is not accessible to the authenticated user (private project, non-member, guest role without access).

Common situations: AI agents referencing builds in another project the user cannot see; users whose project membership was revoked; cross-project build references in shared chat sessions.

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