{"record":{"id":"140a5b5172b892b6","repo":"theonedev/onedev","slug":"not-authorized-140a5b","errorCode":null,"errorMessage":"Not authorized","messagePattern":"Not authorized","errorType":"http","errorClass":"UnauthorizedException","httpStatus":403,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/TriggerJobResource.java","lineNumber":113,"sourceCode":"\t\treturn triggerJob(projectPath, branch, tag, job, accessToken, uriInfo);\n    }\n\n    private Long triggerJob(String projectPath, @Nullable String branch, @Nullable String tag, String job,\n\t\t\t\t\t\t\tString accessTokenValue, UriInfo uriInfo) {\n\t\tProject project = projectService.findByPath(projectPath);\n\t\tif (project == null)\n\t\t\tthrow new NotAcceptableException(\"Project not found: \" + projectPath);\n\n\t\tvar accessToken = accessTokenService.findByValue(accessTokenValue);\n\t\tif (accessToken == null)\n\t\t\tthrow new NotAcceptableException(\"Invalid access token\");\n\t\t\n\t\tvar subject = accessToken.asSubject();\n\t\tvar user = SecurityUtils.getUser(subject);\n\t\tThreadContext.bind(subject);\n\t\ttry {\n\t\t\tif (!SecurityUtils.canRunJob(subject, project, job))\t\t\n\t\t\t\tthrow new UnauthorizedException();\n\n\t\t\tif (StringUtils.isNotBlank(branch) && StringUtils.isNotBlank(tag)) \n\t\t\t\tthrow new NotAcceptableException(\"Either branch or tag should be specified, but not both\");\n\t\t\t\n\t\t\tString refName;\n\t\t\tif (branch != null)\n\t\t\t\trefName = GitUtils.branch2ref(branch);\n\t\t\telse if (tag != null)\n\t\t\t\trefName = GitUtils.tag2ref(tag);\n\t\t\telse\n\t\t\t\trefName = GitUtils.branch2ref(project.getDefaultBranch());\n\t\t\t\n\t\t\tRevCommit commit = project.getRevCommit(refName, false);\n\t\t\tif (commit == null)\n\t\t\t\tthrow new NotAcceptableException(\"Ref not found: \" + refName);\n\t\t\t\n\t\t\tMap<String, List<String>> jobParams = new HashMap<>();\n\t\t\tfor (Map.Entry<String, List<String>> entry: uriInfo.getQueryParameters().entrySet()) {","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/TriggerJobResource.java#L95-L131","documentation":"The token's subject is bound to the security context and SecurityUtils.canRunJob(subject, project, job) checks whether the user may run the named job in the project. If not, UnauthorizedException is thrown. Even a valid token fails here if its user lacks job-run (project member/report permissions) rights or the job doesn't exist in that project.","triggerScenarios":"GET/POST /~api/trigger-job with a valid access token whose owner is not authorized to run the specified job in the target project (not a project member, insufficient role), or referencing a job name the user cannot run.","commonSituations":"Using a personal token of a user not added to the project; token belongs to another user than assumed; project role downgraded; CI bot account never granted access to the new project.","solutions":["Add the token's user to the target project with a role that can run jobs, or ask a project admin for access.","Verify the job name matches a job defined in the project's build spec and that the user's role permits running it.","Use a token of a user who is at least a project user with job-run permission (e.g. Project Developer+ depending on setup)."],"exampleFix":"// before: token of outsider user\ncurl 'http://onedev/~api/trigger-job?project=myorg/myrepo&job=CI&access_token=TOKEN'\n// after: grant the token's user role in project, or use an admin/member token\nOneDev UI: Project myorg/myrepo > People > add user 'ci-bot' as Developer; retry","handlingStrategy":"validation","validationCode":"const project = await getProject(projectPath);\nconst members = await fetch(`/~api/projects/${project.id}/authorizations`, {headers: {Authorization: auth}}).then(r => r.json());\nconst me = await fetch('/~api/me', {headers: {Authorization: auth}}).then(r => r.json());\nif (!members.some(m => m.userName === me.userName))\n  throw new Error('Token user is not a member of the target project');","typeGuard":null,"tryCatchPattern":"try {\n  return await triggerJob(params);\n} catch (e) {\n  if (e.status === 406 && /not authorized/i.test(e.message))\n    throw new Error(`User of token cannot run job '${params.job}' in '${params.project}' - grant project access`);\n  throw e;\n}","preventionTips":["Add the CI bot user to every project it triggers jobs in.","Use one token per project scope.","Audit role changes after project restructuring."],"tags":["rest-api","authorization","access-token","ci-cd","onedev"],"backgroundTag":"insufficient-permissions","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"}