{"record":{"id":"7309e04afea92a8c","repo":"theonedev/onedev","slug":"no-permission-to-read-code-of-source-project","errorCode":null,"errorMessage":"No permission to read code of source project: ","messagePattern":"No permission to read code of source project: ","errorType":"http","errorClass":"UnauthorizedException","httpStatus":403,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/ai/TodResource.java","lineNumber":1275,"sourceCode":"                String currentProjectPath, \n                @Nullable String targetProjectPath, \n                @Nullable String sourceProjectPath,\n                @Nullable String targetBranch, \n                String sourceBranch) {\n        var user = SecurityUtils.getUser();\n        if (user == null)\n            throw new UnauthenticatedException();\n        \n        var currentProject = getProject(currentProjectPath);\n\n        Project sourceProject;\n        if (sourceProjectPath == null)\n            sourceProject = currentProject;\n        else\n            sourceProject = getProject(sourceProjectPath);\n\n        if (!SecurityUtils.canReadCode(sourceProject))\n            throw new UnauthorizedException(\"No permission to read code of source project: \" + sourceProjectPath);\n\n        Project targetProject;\n        if (targetProjectPath != null) {\n            targetProject = getProject(targetProjectPath);\n        } else {\n            targetProject = sourceProject.getForkedFrom();\n            if (targetProject == null)\n                targetProject = sourceProject;\n        }\n        if (!SecurityUtils.canReadCode(targetProject))\n            throw new UnauthorizedException(\"No permission to read code of target project: \" + targetProjectPath);\n\n        if (targetBranch == null)\n            targetBranch = targetProject.getDefaultBranch();\n        if (targetBranch == null)\n            throw new NotAcceptableException(\"No code in target project: \" + targetProject.getPath());\n\n        var target = new ProjectAndBranch(targetProject, targetBranch);","sourceCodeStart":1257,"sourceCodeEnd":1293,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/ai/TodResource.java#L1257-L1293","documentation":"When creating a pull request via the TOD endpoint, OneDev checks SecurityUtils.canReadCode(sourceProject) for the resolved source project (either currentProject or the project at sourceProjectPath). If the current user lacks code-read permission, it throws a JAX-RS UnauthorizedException (HTTP 401/403) naming the source project path.","triggerScenarios":"POST to the create-pull-request endpoint with a sourceProjectPath the authenticated user cannot read code in, or when the user has no code access to currentProject.","commonSituations":"API token/account missing project-level 'Read code' permission; referencing another team's project as source; project visibility changed recently.","solutions":["Grant the user (or their group) 'Read code' permission on the source project in project > access control.","Use a source project the account can actually read.","Authenticate as a user/token with sufficient privileges."],"exampleFix":"// before\nvar params = \"currentProject=team-a/app&sourceProjectPath=team-b/lib\";\n// after — grant user Read code on team-b/lib, or use an accessible project\nvar params = \"currentProject=team-a/app\";","handlingStrategy":"validation","validationCode":"Project sourceProject = sourceProjectPath != null ? getProject(sourceProjectPath) : currentProject;\nif (!SecurityUtils.canReadCode(sourceProject))\n    throw new IllegalStateException(\"Current user cannot read code in \" + sourceProject.getPath());","typeGuard":null,"tryCatchPattern":"try {\n    callCreatePullRequest(params);\n} catch (UnauthorizedException e) {\n    if (e.getMessage().startsWith(\"No permission to read code of source project\")) {\n        // surface an actionable message: request access to the project\n    } else throw e;\n}","preventionTips":["Check the token/user's project permissions before automating PR creation.","Prefer projects the authenticated account already contributes to as source.","Keep group/project permission assignments in sync when teams change."],"tags":["permissions","pull-request","authorization","onedev"],"backgroundTag":"permission-denied","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}