{"record":{"id":"2151640fb0101b73","repo":"theonedev/onedev","slug":"no-package-write-permission-for-project-project-215164","errorCode":null,"errorMessage":"No package write permission for project: ${project.getPath()}","messagePattern":"No package write permission for project: (.+?)","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"server-plugin/server-plugin-pack-helm/src/main/java/io/onedev/server/plugin/pack/helm/HelmPackHandler.java","lineNumber":259,"sourceCode":"                packService.createOrUpdate(pack, List.of(packBlob), true);\n                response.setStatus(SC_CREATED);\n            }));\n        } else {\n            throw new ClientException(SC_METHOD_NOT_ALLOWED, \"Method not allowed\");\n        }\n    }\n\n    @Override\n    public String getApiKey(HttpServletRequest request) {\n        return null;\n    }\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\t} else if (needsToWrite && !SecurityUtils.canWritePack(project)) {\n\t\t\tthrow new UnauthorizedException(\"No package write permission for project: \" + project.getPath());\n\t\t} else if (!needsToWrite && !SecurityUtils.canReadPack(project)) {\n\t\t\tthrow new UnauthorizedException(\"No package read permission for project: \" + project.getPath());\n\t\t}\n\t\treturn project;\n\t}\n\n\tprivate String getDownloadUrl(Pack pack) {\n\t\treturn String.format(\"/%s/~helm/%s-%s.tgz\",\n\t\t\t\tpack.getProject().getPath(), pack.getName(), pack.getVersion());\n\t}\n\n\t@Override\n\tpublic List<String> normalize(List<String> pathSegments) {\n        pathSegments = new ArrayList<>(pathSegments);\n        if (pathSegments.get(pathSegments.size() - 1).equals(\"charts\")) {\n            pathSegments.remove(pathSegments.size() - 1);\n            if (pathSegments.get(0).equals(\"api\")) \n                pathSegments.remove(0);","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-plugin/server-plugin-pack-helm/src/main/java/io/onedev/server/plugin/pack/helm/HelmPackHandler.java#L241-L277","documentation":"checkProject throws UnauthorizedException when a write operation (publish/upload) is requested and SecurityUtils.canWritePack(project) is false — the authenticated user lacks package write permission on the project.","triggerScenarios":"POST/PUT of a chart to /~helm by a user who can read but not write packs; CI job tokens without write scope; anonymous or read-only accounts attempting to publish.","commonSituations":"Deploy pipelines using a read-only access token, users not added to a role with 'Write packages' permission, or publishing to a project where only maintainers may write packs.","solutions":["Grant the user/job token package write permission (role with 'Write packages' on the project)","Switch the CI job to an access token/account with pack write access","Verify you are publishing to a project you are a member of with sufficient role","Check Project -> Access Control and the job's token permissions"],"exampleFix":"// before: read-only token\ncurl -H \"Authorization: Bearer <read-token>\" -T chart.tgz ...\n// after: use a token with pack write permission\ncurl -H \"Authorization: Bearer <write-token>\" -T chart.tgz ...","handlingStrategy":"validation","validationCode":"// before publishing, verify access\nvar me = GET /api/auth/user\nvar acl = GET /api/projects/{path}/authorizations\nif (!acl.canWritePack) throw new SecurityException(\"token lacks pack write permission\");","typeGuard":null,"tryCatchPattern":"try { publishChart(); } catch (UnauthorizedException e) { log.error(\"no pack write permission: {}\", e.getMessage()); requestWriteAccess(); }","preventionTips":["Use dedicated CI tokens with pack write scope","Grant publishing roles 'Write packages' permission","Test publish with a dry run before automated deploys"],"tags":["helm","authorization","permissions","publish"],"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"}