{"record":{"id":"62f71d419a2075b7","repo":"theonedev/onedev","slug":"package-already-exists-name-name-version","errorCode":null,"errorMessage":"Package already exists (name: ${name}, version: ${version})","messagePattern":"Package already exists \\(name: (.+?), version: (.+?)\\)","errorType":"http","errorClass":"ClientException","httpStatus":409,"severity":"error","filePath":"server-plugin/server-plugin-pack-pypi/src/main/java/io/onedev/server/plugin/pack/pypi/PypiPackHandler.java","lineNumber":172,"sourceCode":"\t\t\t\t\t\t\t\t\t\tpack.setName(name);\n\t\t\t\t\t\t\t\t\t\tpack.setVersion(version);\n\t\t\t\t\t\t\t\t\t\tpack.setProject(project);\n\t\t\t\t\t\t\t\t\t\tdata = new PypiData(attributes, new LinkedHashMap<>());\n\t\t\t\t\t\t\t\t\t\tpack.setData(data);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tdata = (PypiData) pack.getData();\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tBuild build = null;\n\t\t\t\t\t\t\t\t\tif (buildId != null)\n\t\t\t\t\t\t\t\t\t\tbuild = buildService.load(buildId);\n\t\t\t\t\t\t\t\t\tpack.setBuild(build);\n\t\t\t\t\t\t\t\t\tpack.setUser(SecurityUtils.getUser());\n\t\t\t\t\t\t\t\t\tpack.setPublishDate(new Date());\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\tif (data.getSha256BlobHashes().containsKey(fileName)) {\n\t\t\t\t\t\t\t\t\t\tvar errorMessage = String.format(\"Package already exists (name: %s, version: %s)\", name, version);\n\t\t\t\t\t\t\t\t\t\tthrow new ClientException(SC_CONFLICT, errorMessage);\n\t\t\t\t\t\t\t\t\t} \n\t\t\t\t\t\t\t\t\tdata.getSha256BlobHashes().put(fileName, sha256Hash);\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\tvar packBlobs = data.getSha256BlobHashes().values().stream()\n\t\t\t\t\t\t\t\t\t\t\t.map(hash -> packBlobService.findBySha256Hash(projectId, hash))\n\t\t\t\t\t\t\t\t\t\t\t.filter(Objects::nonNull)\n\t\t\t\t\t\t\t\t\t\t\t.collect(toList());\n\t\t\t\t\t\t\t\t\tpackService.createOrUpdate(pack, packBlobs, data.getSha256BlobHashes().size() == 1);\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t}));\n\t\t\t\t\t\t\t\tresponse.setStatus(SC_OK);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (IOException | FileUploadException e) {\n\t\t\t\t\tthrow new RuntimeException(e);\n\t\t\t\t}\n\t\t\t} else {","sourceCodeStart":154,"sourceCodeEnd":190,"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#L154-L190","documentation":"When publishing a PyPI package, if the pack's data already records the same file name in its sha256BlobHashes map, the package (name+version) is considered already published and a ClientException with HTTP 409 (Conflict) 'Package already exists' is thrown. OneDev does not overwrite an existing package version.","triggerScenarios":"Re-running a CI publish step without bumping the version; uploading the same package version a second time; publishing an artifact whose filename already exists in the target pack version.","commonSituations":"Manual pipeline retries, mutable/latest version tags instead of unique semantic versions, sharing one pack version across different branch builds.","solutions":["Bump the package version and republish.","Delete the existing package version in OneDev (pack management UI) if it should be replaced, then republish.","Make the CI publish step idempotent: skip publishing if the version already exists, or use a unique version like a build-number suffix."],"exampleFix":"// before\nversion=1.0.0  # already published, rerun fails\n// after\nversion=1.0.1  # or delete existing pack version in OneDev before re-running publish","handlingStrategy":"try-catch","validationCode":"# check whether the pack version already exists before publishing\nexists = requests.get(f'{base}/api/packs?project={pid}&type=pypi&name={name}&version={version}').ok","typeGuard":null,"tryCatchPattern":"if resp.status_code == 409 and 'Package already exists' in resp.text:\n    bump_version_and_retry()","preventionTips":["Never republish the same version; make versions unique per build.","Make CI publish steps idempotent (check-then-publish or skip-if-exists).","Clean up stale versions deliberately via the pack management UI."],"tags":["pypi","http-409","conflict","duplicate"],"backgroundTag":"file-already-exists","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"}