I like the approach that Rust takes with Cargo and crates.io
You can mark a package you’ve published as “yanked”, which will make it so that if someone tries to depend on that version in the future they “can’t” (cargo will tell you it’s yanked). But if it’s in your Cargo.lock file since before, cargo will still fetch it and use it.
This way you can mark a broken version of your published package as bad so that fewer people will use that version. While not preventing anyone who was already using it from continuing to use it.