Summary
sdk uninstall fails when the installed version directory no longer exists (e.g. a local install pointing to a deleted or moved external path). This leaves SDKMAN! in a catch-22 state where the version cannot be uninstalled or reinstalled.
Originally reported in sdkman/sdkman-cli#407 (2016). The bug persists in the Rust implementation.
Steps to reproduce
- Install a local version pointing to an external path:
sdk install gradle myver /some/external/path
- Delete or move the external path:
rm -rf /some/external/path
- Attempt to uninstall:
Actual behaviour
gradle myver is not installed on your system
But attempting to reinstall:
sdk install gradle myver /some/other/path
→ Stop! gradle myver is already installed.
The version entry (a broken symlink) still exists under ~/.sdkman/candidates/gradle/myver, but validate_version_path rejects it because the target directory is gone.
Expected behaviour
sdk uninstall should succeed when the version entry exists in the candidates directory, even if the underlying target has been deleted. It should clean up the broken symlink/directory entry and report success.
Root cause
validate_version_path in src/lib.rs (line 77) checks:
if version_path.exists() && version_path.is_dir()
Path::exists() returns false for broken symlinks. The function should also check for broken symlinks (e.g. version_path.symlink_metadata().is_ok()) or the uninstall command should handle the missing-target case separately.
Suggested fix
In the uninstall command, relax the validation: if the version directory entry exists as a symlink (even broken) or as a directory, proceed with removal. fs::remove_dir_all handles broken symlinks fine — the issue is purely in the pre-validation gate.
Summary
sdk uninstallfails when the installed version directory no longer exists (e.g. a local install pointing to a deleted or moved external path). This leaves SDKMAN! in a catch-22 state where the version cannot be uninstalled or reinstalled.Originally reported in sdkman/sdkman-cli#407 (2016). The bug persists in the Rust implementation.
Steps to reproduce
Actual behaviour
But attempting to reinstall:
→
Stop! gradle myver is already installed.The version entry (a broken symlink) still exists under
~/.sdkman/candidates/gradle/myver, butvalidate_version_pathrejects it because the target directory is gone.Expected behaviour
sdk uninstallshould succeed when the version entry exists in the candidates directory, even if the underlying target has been deleted. It should clean up the broken symlink/directory entry and report success.Root cause
validate_version_pathinsrc/lib.rs(line 77) checks:Path::exists()returnsfalsefor broken symlinks. The function should also check for broken symlinks (e.g.version_path.symlink_metadata().is_ok()) or the uninstall command should handle the missing-target case separately.Suggested fix
In the uninstall command, relax the validation: if the version directory entry exists as a symlink (even broken) or as a directory, proceed with removal.
fs::remove_dir_allhandles broken symlinks fine — the issue is purely in the pre-validation gate.