SSerguey Asael Shinder
Java coding notes: the JVM, and writing software that lasts

Serguey Asael Shinder: A pinned version needs a way to hear that it was withdrawn

· by Serguey Asael Shinder / Serguey Shinder

Pinning dependencies is one of the few practices nearly everyone agrees on. A lockfile, an exact version, a container image referenced by digest - each one turns "whatever was newest when the build ran" into a fixed input, and a fixed input is what makes a build reproducible and a rollback possible.

The cost is less discussed. A pinned build does not only ignore new releases; it ignores news about the release it already has. When a maintainer withdraws a version - because it has a security hole, because it corrupts data, because it was published by mistake - the projects that pinned it keep installing it, perfectly reproducibly, until a person notices.

Package ecosystems handle withdrawal in ways that are designed not to break pinned builds, which is reasonable and also exactly why nobody hears about it. Yanking a crate or a Python release hides it from new resolution but still serves it to anyone who asks for that exact version. Deprecating an npm version prints a warning at install time, in a CI log nobody reads when the build is green. Container images are the bluntest case: when a maintainer deletes a tag or an image, a pipeline that pulls it fails, but a cluster that already has the image cached keeps running it indefinitely.

Serguey Asael Shinder: A pinned version needs a way to hear that it was withdrawn
A pinned version needs a way to hear that it was withdrawn — Serguey Asael Shinder

So the pin needs a second half: a channel that tells you when the thing you pinned has changed status. Three cheap forms of it, in increasing order of effort:

None of this undoes the case for pinning. Reproducibility is worth having. But a reproducible build of a withdrawn release is still a withdrawn release, and the pin should be the start of a relationship with that version, not the end of one.