{"record":{"id":"d822d73d56c2e9e0","repo":"theonedev/onedev","slug":"no-package-write-permission-for-project-project-d822d7","errorCode":null,"errorMessage":"No package write permission for project: ${projectPath}","messagePattern":"No package write permission for project: (.+?)","errorType":"exception","errorClass":"UnauthorizedException","httpStatus":null,"severity":"error","filePath":"server-plugin/server-plugin-pack-pypi/src/main/java/io/onedev/server/plugin/pack/pypi/PypiPackHandler.java","lineNumber":303,"sourceCode":"\t@Override\n\tpublic String getApiKey(HttpServletRequest request) {\n\t\treturn null;\n\t}\n\t\n\tprivate void sendResponse(HttpServletResponse response, String content) {\n\t\ttry {\n\t\t\tresponse.getOutputStream().print(content);\n\t\t} catch (IOException e) {\n\t\t\tthrow new RuntimeException(e);\n\t\t}\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\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\t@Override\n\tpublic List<String> normalize(List<String> pathSegments) {\n\t\treturn pathSegments;\n\t}\n\n}\n","sourceCodeStart":285,"sourceCodeEnd":316,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-plugin/server-plugin-pack-pypi/src/main/java/io/onedev/server/plugin/pack/pypi/PypiPackHandler.java#L285-L316","documentation":"checkProject throws UnauthorizedException when a write operation is requested but the current user lacks WritePack permission on the project. Twine uploads and other mutating PyPI operations are rejected.","triggerScenarios":"Twine upload (or any needsToWrite=true endpoint) executed by a user whose effective permission on the project does not include SecurityUtils.canWritePack — e.g. only Read Pack or job-read rights.","commonSituations":"CI job token lacking pack write permission; user added to project with read-only role; permissions changed after a pipeline was set up.","solutions":["Grant the user (or the CI job role) 'Write Pack' permission in project permissions settings","If uploading from a job, ensure the job token has package write permission (e.g. appropriate role/secret)","Verify you are operating against the correct project path"],"exampleFix":"null","handlingStrategy":"validation","validationCode":"var project = projectService.load(projectId);\nif (!SecurityUtils.canWritePack(project)) throw new IllegalStateException('Missing pack write permission on ' + project.getPath());","typeGuard":null,"tryCatchPattern":"try { twineUpload(); } catch (UnauthorizedException e) { grantPackWriteAndRetry(project); }","preventionTips":["Grant CI job roles Write Pack permission when pipelines publish packages","Audit project permissions after role changes","Use a dedicated service account with pack write access for uploads"],"tags":["authorization","permissions","pypi"],"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"}