jdx/mise · error

cannot link to its own install path

Error message

cannot link {} to its own install path

What it means

mise refuses to create a symlink from a tool's install path onto itself — the source `--path` and the destination `installs/<tool>/<version>` are the same file. Doing so would be a no-op or self-referential loop, so it is rejected.

Solutions

  1. Point `--path` at a directory that is not already `<mise data dir>/installs/<tool>/<version>`
  2. If the tool is already installed correctly, no link is needed — run `mise ls` to confirm and skip the link
  3. If you meant to expose a different build, install/link it under a distinct version or ref name

Example fix

// before
mise link node@22.1.0 ~/.local/share/mise/installs/node/22.1.0
// after
mise link node@22.1.0 ~/projects/custom-node-build
Defensive patterns

Strategy: validation

Validate before calling

// bash: skip linking if path is already the install dir
TARGET="$(mise where node@22.1.0 2>/dev/null)"
[[ "$(readlink -f "$PATH_TO_LINK")" == "$TARGET" ]] && exit 0

Prevention

When it happens

Trigger: Calling `mise link node@22.1.0 ~/.local/share/mise/installs/node/22.1.0` — the given path is already the target install location for that exact tool version.

Common situations: Users 're-registering' an already-installed tool by linking its install dir back, or copying a link command from another machine with a shared install directory.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/a6776e88b17a69f1. Report an issue: GitHub.

Appendix: source

Thrown at src/cli/link.rs:85

                        "mise link only supports concrete versions and refs, not {}",
                        tvr.version()
                    );
                }
                ToolVersion::new(tvr.clone(), version.clone()).tv_pathname()
            }
            ToolRequest::Ref { .. } => ToolVersion::new(tvr.clone(), tvr.version()).tv_pathname(),
            _ => unreachable!(),
        };
        let path = self.path.absolutize()?;
        if !path.exists() {
            warn!(
                "Target path {} does not exist",
                style(path.to_string_lossy()).cyan().for_stderr()
            );
        }
        let target = self.tool.ba.installs_path.join(&version_pathname);
        if !file::is_symlink_to(&target, &path) && file::same_file(&path, &target) {
            bail!("cannot link {} to its own install path", self.tool.style());
        }
        {
            let _state_lock =
                install_state::lock_tool_version(&self.tool.ba.short, &version_pathname)?;
            if !file::is_symlink_to(&target, &path) {
                if target.exists() {
                    if self.force {
                        remove_all(&target)?;
                    } else {
                        return Err(eyre!(
                            "Tool version {} already exists, use {} to overwrite",
                            self.tool.style(),
                            style("--force").yellow().for_stderr()
                        ));
                    }
                }
                file::create_dir_all(target.parent().unwrap())?;
                make_symlink(&path, &target)?;

View on GitHub (pinned to 533346cc37)