{"record":{"id":"85b744e16ae3456c","repo":"theonedev/onedev","slug":"no-permission-to-access-specified-issues","errorCode":null,"errorMessage":"No permission to access specified issues","messagePattern":"No permission to access specified issues","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/IssueLinkResource.java","lineNumber":52,"sourceCode":"\tpublic IssueLinkResource(IssueLinkService linkService) {\n\t\tthis.linkService = linkService;\n\t}\n\n\t@Api(order=100)\n\t@Path(\"/{linkId}\")\n\t@GET\n\tpublic IssueLink getLink(@PathParam(\"linkId\") Long linkId) {\n\t\tvar link = linkService.load(linkId);\n\t\tif (!canAccessIssue(link.getTarget()) && !canAccessIssue(link.getSource()))\n\t\t\tthrow new UnauthorizedException();\n\t\treturn link;\n\t}\n\t\n\t@Api(order=200, description=\"Create new issue link\")\n\t@POST\n\tpublic Long createLink(@NotNull IssueLink link) {\n\t\tif (!canAccessIssue(link.getSource()) || !canAccessIssue(link.getTarget()))\n\t\t\tthrow new UnauthorizedException(\"No permission to access specified issues\");\n\t\tif (!canEditIssueLink(link.getSource().getProject(), link.getSpec())\n\t\t\t\t|| !canEditIssueLink(link.getTarget().getProject(), link.getSpec())) {\n\t\t\tthrow new UnauthorizedException(\"No permission to add specified link for specified issues\");\n\n\t\t}\n\t\tlink.validate();\n\t\t\t\t\t\t\n\t\tlinkService.create(link);\n\t\treturn link.getId();\n\t}\n\t\n\t@Api(order=300)\n\t@Path(\"/{linkId}\")\n\t@DELETE\n\tpublic Response deleteLink(@PathParam(\"linkId\") Long linkId) {\n\t\tvar link = linkService.load(linkId);\n\t\tif (!canEditIssueLink(link.getSource().getProject(), link.getSpec()) \n\t\t\t\t&& !canEditIssueLink(link.getTarget().getProject(), link.getSpec())) {","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/IssueLinkResource.java#L34-L70","documentation":"POST /issueLinks (createLink) throws UnauthorizedException(\"No permission to access specified issues\") when the caller cannot access either the source or the target issue of the link. canAccessIssue() checks that the authenticated user can read the issue's project and that the issue is not confidential to them. OneDev requires visibility of both ends before linking issues.","triggerScenarios":"POST /~api/issueLinks with a link whose source or target issue (a) belongs to a project the user cannot access, or (b) is confidential and the user is not the reporter/a user who can access confidential issues.","commonSituations":"Linking an issue in a private project with an issue in a public one using a limited token; linking to a confidential issue reported by someone else; project visibility changed after the script was written; stale issue ids from another environment.","solutions":["Confirm both issue ids exist and are in projects your token can read (GET each issue first).","Use a token with access to both projects involved.","If the target is confidential, either use the reporter's token or make the issue non-confidential.","Adjust your account's project membership to include the inaccessible project."],"exampleFix":"// before\nclient.createIssueLink(new IssueLink().source(srcIssue).target(dstIssue));\n// after: pre-check access\nif (!canRead(srcIssue) || !canRead(dstIssue))\n    throw new IllegalArgumentException(\"token cannot access both issues\");\nclient.createIssueLink(new IssueLink().source(srcIssue).target(dstIssue));","handlingStrategy":"validation","validationCode":"// both issues must be readable by the token user before linking\nfor (var issue : List.of(sourceId, targetId)) {\n    var loaded = client.getIssue(issue); // throws if inaccessible\n    if (loaded == null) throw new IllegalStateException(\"issue \" + issue + \" not accessible\");\n}","typeGuard":null,"tryCatchPattern":"try { client.createIssueLink(link); }\ncatch (UnauthorizedException e) {\n    if (e.getMessage().contains(\"access specified issues\")) log.warn(\"Check visibility/confidentiality of issues {} -> {}\", sourceId, targetId);\n}","preventionTips":["GET both issues before linking to confirm read access.","Handle confidential issues: only link with reporter or privileged tokens.","Refresh cached issue ids after project visibility changes."],"tags":["rest-api","issues","authorization","confidential"],"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"}