theonedev/onedev · error · org.apache.shiro.authz.UnauthorizedException
No permission to access build
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.
Solutions
- Ask an administrator to grant the user appropriate access to the referenced build's project.
- Use a build reference within a project the current user can access.
- 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
- Check project membership before referencing cross-project builds
- Keep AI agents scoped to projects the invoking user can access
- Document required roles for tools that resolve build references
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
- Issue schedule permission required to set iterations
- Issue schedule permission required to set own estimated time
- Issue schedule permission required to set own estimated…
- No permission to access specified issues
- No permission to add specified link for specified issues
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/3a7157e172a46f21.
Report an issue: GitHub.
Appendix: 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)