theonedev/onedev · error · UnauthorizedException
Unauthorized
Error message
Unauthorized
What it means
PatchResource serves generated patch files for project commits. Outside the system security context it loads the project and throws UnauthorizedException when SecurityUtils.canReadCode(project) is false — patch content is considered code, so code read permission is mandatory. The resource framework returns it as HTTP 401/403 "Unauthorized".
Source
Thrown at server-core/src/main/java/io/onedev/server/web/resource/PatchResource.java:65
protected ResourceResponse newResourceResponse(Attributes attributes) {
PageParameters params = attributes.getParameters();
Long projectId = params.get(PARAM_PROJECT).toLong();
var oldCommitId = ObjectId.fromString(params.get(PARAM_OLD_COMMIT).toString());
var newCommitId = ObjectId.fromString(params.get(PARAM_NEW_COMMIT).toString());
var forCodeReview = params.get(PARAM_FOR_CODE_REVIEW).toBoolean(false);
String excludedFiles;
if (forCodeReview) {
Project project = getProjectService().load(projectId);
excludedFiles = project.findExcludedAiReviewFiles();
} else {
excludedFiles = null;
}
if (!SecurityUtils.isSystem()) {
Project project = getProjectService().load(projectId);
if (!SecurityUtils.canReadCode(project))
throw new UnauthorizedException();
}
ResourceResponse response = new ResourceResponse();
response.getHeaders().addHeader("X-Content-Type-Options", "nosniff");
response.setContentType(MimeTypes.OCTET_STREAM);
response.setFileName(URLEncoder.encode("changes.patch", UTF_8));
response.setWriteCallback(new WriteCallback() {
@Override
public void writeData(Attributes attributes) throws IOException {
String activeServer = getProjectService().getActiveServer(projectId, true);
if (activeServer.equals(getClusterService().getLocalServerAddress())) {
try (var os = attributes.getResponse().getOutputStream()) {
var repository = getProjectService().getRepository(projectId);
GitUtils.diff(repository, oldCommitId, newCommitId, excludedFiles, os);View on GitHub (pinned to d44925c47c)
Solutions
- Authenticate as a user with 'Read Code' permission on the project.
- Grant the requesting user/role Read Code in project access settings.
- If fetching programmatically, use an access token with code read scope.
Example fix
// before: anonymous fetch of patch -> 401 curl https://onedev.example.com/~resource/patches/1/abcdef // after curl -u user:password https://onedev.example.com/~resource/patches/1/abcdef
Defensive patterns
Strategy: validation
Validate before calling
// ensure the caller can read code before requesting patches
if (!userCan('READ_CODE', projectId)) {
throw new Error('fetching patches requires Read Code permission on project ' + projectId);
} Try / catch
try { fetchPatch(url); } catch (HttpException e) { if (e.getStatusCode() === 401 || e.getStatusCode() === 403) promptForCredentials(); else throw e; } Prevention
- Authenticate before using patch URLs
- Update shared links when a project changes from public to private
- Give export/report tooling a token with code read access
When it happens
Trigger: GET of the patch resource URL (e.g. /~resource/patches/...) by a user without Read Code permission on the project — anonymous access to a private project, or a role limited to issues/builds.
Common situations: Sharing patch links externally while the repository is private; bots/crawlers hitting patch URLs; a formerly public project made private so previously working links start failing.
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.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Project not specified
- Project not found or inaccessible: <projectPath>
- Authentication required
- You do not have permission to pull from this project.
- You do not have permission to push to this project.
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/44e3ad66ff26e094.
Report an issue: GitHub.