{"record":{"id":"05c226481816f45d","repo":"theonedev/onedev","slug":"no-package-read-permission-for-project","errorCode":null,"errorMessage":"No package read permission for project: ","messagePattern":"No package read permission for project: ","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"server-plugin/server-plugin-pack-npm/src/main/java/io/onedev/server/plugin/pack/npm/NpmPackHandler.java","lineNumber":585,"sourceCode":"\t}\n\n\t@Override\n\tpublic String getApiKey(HttpServletRequest request) {\n\t\tvar authzHeader = request.getHeader(HttpHeaders.AUTHORIZATION);\n\t\tif (authzHeader != null&& authzHeader.toLowerCase().startsWith(\"bearer \")) \n\t\t\treturn StringUtils.substringAfter(authzHeader, \" \");\n\t\telse\n\t\t\treturn null;\n\t}\n\n\tprivate Project checkProject(Long projectId, boolean needsToWrite) {\n\t\tvar project = projectService.load(projectId);\n\t\tif (!project.isPackManagement())\n\t\t\tthrow new ClientException(SC_NOT_ACCEPTABLE, \"Package management not enabled for project '\" + project.getPath() + \"'\");\n\t\telse if (needsToWrite && !SecurityUtils.canWritePack(project))\n\t\t\tthrow new UnauthorizedException(\"No package write permission for project: \" + project.getPath());\n\t\telse if (!needsToWrite && !SecurityUtils.canReadPack(project))\n\t\t\tthrow new UnauthorizedException(\"No package read permission for project: \" + project.getPath());\n\t\treturn project;\n\t}\n\t\n\t@Override\n\tpublic List<String> normalize(List<String> pathSegments) {\n\t\treturn pathSegments;\n\t}\n\n}\n","sourceCodeStart":567,"sourceCodeEnd":595,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-plugin/server-plugin-pack-npm/src/main/java/io/onedev/server/plugin/pack/npm/NpmPackHandler.java#L567-L595","documentation":"Thrown by checkProject when a read operation (npm metadata fetch or tarball download) is attempted by a user who lacks pack read permission on the project. It raises UnauthorizedException, surfaced as HTTP 401 to the npm client.","triggerScenarios":"GET metadata or tarball where SecurityUtils.canReadPack(project) is false — no/invalid Bearer token, or the token's user has no read access to the project's packages.","commonSituations":"Anonymous npm install from a private project; expired or revoked access token in .npmrc; CI job token from a different project trying to read packages of another project; public access disabled on the project.","solutions":["Add a read-capable access token to .npmrc for the OneDev host.","Grant the user or job's role at least Pack Read permission on the project.","Verify the token is valid and not expired (User Profile -> Access Tokens).","If packages should be public, enable public read access for the project in its settings."],"exampleFix":"// before — no token, private project\nregistry=https://onedev.example.com/npm/proj/\n// after\nregistry=https://onedev.example.com/npm/proj/\n//onedev.example.com/:_authToken=<token-with-pack-read>","handlingStrategy":"try-catch","validationCode":"// Pre-check read access before install\nconst resp = await fetch(`${registryUrl}/${pkgName}`, { headers: { Authorization: `Bearer ${token}` } });\nif (resp.status === 401) throw new Error('No pack read permission: configure a valid access token in .npmrc');","typeGuard":null,"tryCatchPattern":"try {\n  await npmInstall();\n} catch (e) {\n  if (e.code === 'E401') {\n    console.error('Install unauthorized: add //onedev.example.com/:_authToken=<token-with-pack-read> to .npmrc');\n  } else throw e;\n}","preventionTips":["Add read-capable tokens to .npmrc for private packages.","Grant CI jobs Pack Read on projects whose packages they consume.","Enable public read if packages are meant to be anonymous-accessible."],"tags":["npm","http-401","authorization"],"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"}