-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Describe the bug
If a project name is recycled, all previous file uploads for that project persist. This means it is not possible to upload a release with a name and version for a project whose name has been recycled.
A specific example: I own the PyPI record for xbuild
. I successfully published v0.0.1 on September 5 2025. I was using Trusted Publishing workflows, triggered from a Github actions workflow; xbuild-0.0.1
was published to both Test PyPI and Production PyPI.
On September 10, I attempted to publish xbuild v0.1.0. The upload to Test PyPI succeeded; but the upload to Production PyPI failed, with an error message that "the filename is already in use". I downloaded the built wheel and attempted to upload the wheel manually with twine, and got the following response (with verbose logging turned on):
% twine upload ~/Downloads/xbuild-0.1.0-py3-none-any.whl --verbose
INFO Using configuration from /Users/rkm/.pypirc
Uploading distributions to https://upload.pypi.org/legacy/
INFO /Users/rkm/Downloads/xbuild-0.1.0-py3-none-any.whl (17.8 KB)
INFO username set by command options
INFO password set from config file
INFO username: __token__
INFO password: <hidden>
Uploading xbuild-0.1.0-py3-none-any.whl
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 29.8/29.8 kB • 00:00 • 50.6 MB/s
INFO Response from https://upload.pypi.org/legacy/:
400 This filename has already been used, use a different version. See https://pypi.org/help/#file-name-reuse for more information.
INFO <html>
<head>
<title>400 This filename has already been used, use a different version. See https://pypi.org/help/#file-name-reuse for more information.</title>
</head>
<body>
<h1>400 This filename has already been used, use a different version. See https://pypi.org/help/#file-name-reuse for more information.</h1>
The server could not comply with the request since it is either malformed or otherwise incorrect.<br/><br/>
This filename has already been used, use a different version. See https://pypi.org/help/#file-name-reuse for more information.
</body>
</html>
ERROR HTTPError: 400 Bad Request from https://upload.pypi.org/legacy/
This filename has already been used, use a different version. See https://pypi.org/help/#file-name-reuse for more information.
After some investigation, I was eventually able to discover via Clickhouse that there was a previous xbuild project, published in 2023.
Prior to this point, I was unaware that xbuild was a "recycled" project name. I have been able to work around the issue by jumping to v0.2.0, which is a higher version number than anything that the "historical" version of the project ever used.
It is not possible to pip install
any of the older deleted versions. The file exists and can be downloaded from files.pythonhosted.org
- but you need to know the exact hashed filename to request.
Expected behavior
Either:
- Deleting a project should also delete the wheels for that project from
files.pythonhosted.org
; or - It should be possible to re-use filenames that only exist on deleted versions of a project; or
- There should be some way for project maintainers to know that their project name is "recycled", and to see the project versions that won't be usable.
At the very least, the error message should highlight that the issue with a "filename already in use" could be a deleted project.
To Reproduce
- Create a new project on PyPI
- Upload a wheel/tarball release for that project
- Delete the project from PyPI
- Create a new project with the same name
- Make a small modification to the project source, and re-release with the same version number
- Attempt to upload that version with the same version number.
Step 5 is required to ensure that the new release asset has a different file hash.
My Platform
I tested this on macOS; but the wheel in question is a py3-none-any wheel, uploaded via Github Actions Trusted Publisher workflows with v1.13.0 of the pypa/gh-action-pypi-publish workflow. I have no reason to believe it is platform specific, however.
Additional context