{"record":{"id":"2eeb092502923449","repo":"theonedev/onedev","slug":"no-permission-to-read-code-of-target-project","errorCode":null,"errorMessage":"No permission to read code of target project: ","messagePattern":"No permission to read code of target project: ","errorType":"http","errorClass":"UnauthorizedException","httpStatus":403,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/ai/TodResource.java","lineNumber":1286,"sourceCode":"        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);\n        var source = new ProjectAndBranch(sourceProject, sourceBranch);\n\n        var info = new CreatePullRequestEssentialInfo();\n        info.currentProject = currentProject;\n        info.target = target;\n        info.source = source;\n        info.submitter = user;\n\n        return info;\n    }    \n","sourceCodeStart":1268,"sourceCodeEnd":1304,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/ai/TodResource.java#L1268-L1304","documentation":"The TOD create-pull-request endpoint checks SecurityUtils.canReadCode(targetProject) for the target project (explicit targetProjectPath, or the source project's fork parent). Without code-read permission it throws a JAX-RS UnauthorizedException naming the target project path.","triggerScenarios":"POST to create-pull-request where targetProjectPath points to a project the user cannot read code in, or where targetProjectPath is omitted and the fork parent (sourceProject.getForkedFrom()) is inaccessible.","commonSituations":"Cross-fork PR where user can read the fork but not the upstream project; typo in target project path resolving to a restricted project; missing group permissions after team change.","solutions":["Grant 'Read code' permission on the target project to the calling user/group.","Explicitly pass a targetProjectPath you are allowed to read instead of relying on fork resolution.","Verify the fork relationship: target defaults to the forked-from project."],"exampleFix":"// before\n// no targetProjectPath; fork parent team-b/lib not readable\n// after\nparams.put(\"targetProjectPath\", \"team-a/forked-lib\"); // readable target","handlingStrategy":"validation","validationCode":"Project targetProject = targetProjectPath != null ? getProject(targetProjectPath)\n        : (sourceProject.getForkedFrom() != null ? sourceProject.getForkedFrom() : sourceProject);\nif (!SecurityUtils.canReadCode(targetProject))\n    throw new IllegalStateException(\"Current user cannot read code in \" + targetProject.getPath());","typeGuard":null,"tryCatchPattern":"try {\n    callCreatePullRequest(params);\n} catch (UnauthorizedException e) {\n    if (e.getMessage().startsWith(\"No permission to read code of target project\")) {\n        // fall back to a readable fork/target or request access\n    } else throw e;\n}","preventionTips":["When creating cross-fork PRs, verify access to the fork parent first.","Pass targetProjectPath explicitly instead of relying on implicit fork resolution.","Audit fork-related permissions after project restructuring."],"tags":["permissions","pull-request","authorization","fork","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-14T00:17:10.932Z"}