A PyPI release of your library makes a nightly report generator send every report twice — can you re-upload a fixed 1.4.2?
answer
- The index accepts a filename once
- Deleting does not free the number
- Move forward, then discourage the old one
- Pins still resolve, ranges skip it
- Reversible, unlike deletion
basics
~20 sNo. PyPI accepts a given filename once and never again, and deleting it does not free the version number. Ship the fix as 1.4.3, then yank 1.4.2 so resolvers skip it while exact pins still install it.
solid answer
~40 sReleases are immutable: the index rejects an upload whose filename already exists for the project, and deleting a release does not let you reuse that version — the number is spent permanently. So the fix is a new version, 1.4.3, published normally. Then **yank** 1.4.2. A yanked release stays on the index and stays downloadable, but a resolver ignores it unless nothing else satisfies the requirement or the requirement pins it exactly, so existing lockfiles and reproducible builds keep working while every fresh resolution moves past it. Yanking takes a reason string that installers surface as a warning. Deleting instead would hard-break every consumer that pinned 1.4.2 — across a 17-service dependency graph that turns one duplicated side effect into seventeen failing builds — and it is irreversible, whereas a yank can be undone.
go deeper
Remember the hard rule: a version published on PyPI can never be replaced, and deleting it does not let you reuse the number. The fix for a bad release is always a new version.
Explain yank semantics precisely: files stay on the index, resolvers skip them when another candidate fits, exact pins and lockfiles still install them with a warning. Contrast that with deletion, which is irreversible and breaks pinned installs.
Show the incident judgement: publish the patch first, yank with a clear reason, resist deleting under pressure, and recognise that a yank only steers future resolutions while already-installed consumers must be told directly.
Own the policy: when a release is yanked versus deleted, who decides, how consumers are notified across a large dependency graph, and how release practices — rehearsals, staged rollouts, pinned internal consumers — keep a bad version from reaching many services at once.
## Why the answer is no PyPI treats an uploaded file as permanent. Once the index has accepted the wheel file for version 1.4.2, a second upload of a file with that name is rejected. This is not a rate limit or a caching quirk you can wait out: **filenames are never reused**, and because the version is part of the filename, neither are versions. Deleting the release from the project management page does not help either — the name stays burned, so after a delete you cannot publish 1.4.2 at all, ever. The reason is that half the ecosystem assumes it. Lockfiles record hashes of specific files. Mirrors, corporate proxies and build caches keep copies keyed by filename. A reproducible build from six months ago has to keep producing the same bytes. If a version's contents could change, then "we pinned 1.4.2" would mean nothing, and swapping the contents of a popular pinned version would be the single most effective way to attack the ecosystem. ## What you do instead ### 1. Publish the fix as a new version Cut 1.4.3 with the duplicated-side-effect bug fixed and publish it normally. This is the whole remedy for anyone whose requirement is a range: their next resolution picks it up. ### 2. Yank the bad version **Yanking** is the mechanism for saying "this release exists, but do not choose it." It is done on the project's management page on the index, and it takes a short reason string. The install-time semantics are precise and worth stating exactly: * A yanked file **remains on the index** and remains downloadable. Nothing starts returning a 404. * A resolver **ignores yanked candidates** while any non-yanked candidate satisfies the requirement. So a requirement of at least 1.4 now resolves to 1.4.3 and never to 1.4.2. * A yanked file **is still selected** when the requirement can only be satisfied by it — most importantly an exact pin on 1.4.2, and a lockfile entry naming that file. Installers surface the yank reason as a warning when this happens. That combination is the entire point. A pinned deployment does not break; it gets told. A fresh resolution silently does the right thing. You get the effect of a recall without the effect of a deletion. ### 3. Do not delete Deleting removes the file. Every consumer that pinned 1.4.2 — and in a dependency graph spanning seventeen services, some of them will have — fails to install at all, immediately, with no signal beyond "no matching distribution found". You have converted a bug that duplicates a nightly report into a fleet-wide build outage, and you cannot undo it, because the version can never be republished. A yank, by contrast, is reversible: un-yanking restores normal selection. Reserve deletion for something genuinely dangerous that must not be installable, and understand that even then it is not containment, because copies are already on mirrors and in caches. ## The judgement layer Yanking is a resolver hint, not a recall notice. It changes what *future* resolutions choose; it does nothing for the seventeen services that already installed 1.4.2 and are cheerfully sending every report twice tonight. So the yank is the packaging half of the response, and the other half is communication and, where the failure warrants it, an advisory — a separate discipline with its own process. Two practical additions: * **Publish a floor.** If the bug is bad enough that consumers must move, add the constraint in the places you control — your own services' requirements, a lockfile bump — rather than hoping resolvers rerun. Downstream libraries that released with an open-ended lower bound pick up 1.4.3 on their next resolution; ones that pinned will not, and only a human tells them. * **Prefer a yank over a rushed delete under pressure.** The instinct when a release misbehaves is to make it disappear. Deletion is the one action in this whole flow that cannot be walked back, and it makes the blast radius larger, not smaller. ## The version-number question A common follow-on mistake is to try to sneak the fix out as a post-release of 1.4.2. A post-release is legitimate for packaging-only corrections — a broken README, a file missing from the source distribution — because it signals "same code, packaging fixed". A behaviour change is not that. Duplicated side effects are a code bug; it gets a patch release, 1.4.3, so that version ranges and changelogs mean what they say. Getting this distinction right is a real signal of someone who has shipped libraries: the version number is a contract with the resolver, not a label you choose for convenience.
- Who still receives the yanked 1.4.2 after you yank it?Anyone whose requirement can only be satisfied by it: an exact pin on 1.4.2, a lockfile entry naming that file, or a constraint set where no other release qualifies. Installers warn and show the yank reason. Everyone resolving a range gets 1.4.3 instead. That is deliberate — reproducible builds keep working, they just get told.
- Would shipping this fix as a post-release of 1.4.2 be acceptable?No. A post-release means the same code with a packaging correction — a broken README, a file missing from the source distribution. Changing behaviour under a post-release lies to every consumer reading the version, and to any constraint that excludes patch bumps. A code fix gets a patch release, 1.4.3.
- When is deleting a release from the index ever the right call?Almost never for a bug. It is reserved for content that must not be installable at all — a leaked secret baked into the artifact, or actively harmful code — and even then it is not containment, because mirrors and caches already hold copies. It is irreversible, it burns the version number permanently, and it hard-breaks every pinned consumer, which a yank does not.
A yank is leaving a recalled item in the warehouse marked do-not-ship: anyone who asks for it by exact serial number still gets it, with a warning, while ordinary orders quietly get the newer one.
saying these in an interview costs you the question
- Re-uploading the same version after deleting the file
- Believing a yank removes the files from the index
- Thinking a yank fixes installs that already happened
- Using a post-release to ship a behaviour change
- Deleting a release to force consumers to upgrade
- Assuming a pinned consumer stops resolving after a yank