{"record":{"id":"a6776e88b17a69f1","repo":"jdx/mise","slug":"cannot-link-to-its-own-install-path","errorCode":null,"errorMessage":"cannot link {} to its own install path","messagePattern":"cannot link (.+?) to its own install path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/link.rs","lineNumber":85,"sourceCode":"                        \"mise link only supports concrete versions and refs, not {}\",\n                        tvr.version()\n                    );\n                }\n                ToolVersion::new(tvr.clone(), version.clone()).tv_pathname()\n            }\n            ToolRequest::Ref { .. } => ToolVersion::new(tvr.clone(), tvr.version()).tv_pathname(),\n            _ => unreachable!(),\n        };\n        let path = self.path.absolutize()?;\n        if !path.exists() {\n            warn!(\n                \"Target path {} does not exist\",\n                style(path.to_string_lossy()).cyan().for_stderr()\n            );\n        }\n        let target = self.tool.ba.installs_path.join(&version_pathname);\n        if !file::is_symlink_to(&target, &path) && file::same_file(&path, &target) {\n            bail!(\"cannot link {} to its own install path\", self.tool.style());\n        }\n        {\n            let _state_lock =\n                install_state::lock_tool_version(&self.tool.ba.short, &version_pathname)?;\n            if !file::is_symlink_to(&target, &path) {\n                if target.exists() {\n                    if self.force {\n                        remove_all(&target)?;\n                    } else {\n                        return Err(eyre!(\n                            \"Tool version {} already exists, use {} to overwrite\",\n                            self.tool.style(),\n                            style(\"--force\").yellow().for_stderr()\n                        ));\n                    }\n                }\n                file::create_dir_all(target.parent().unwrap())?;\n                make_symlink(&path, &target)?;","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/cli/link.rs#L67-L103","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Point `--path` at a directory that is not already `<mise data dir>/installs/<tool>/<version>`","If the tool is already installed correctly, no link is needed — run `mise ls` to confirm and skip the link","If you meant to expose a different build, install/link it under a distinct version or ref name"],"exampleFix":"// before\nmise link node@22.1.0 ~/.local/share/mise/installs/node/22.1.0\n// after\nmise link node@22.1.0 ~/projects/custom-node-build","handlingStrategy":"validation","validationCode":"// bash: skip linking if path is already the install dir\nTARGET=\"$(mise where node@22.1.0 2>/dev/null)\"\n[[ \"$(readlink -f \"$PATH_TO_LINK\")\" == \"$TARGET\" ]] && exit 0","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check `mise where <tool>@<version>` before linking to avoid self-links","Only link external build directories, never mise's own installs/ tree"],"tags":["cli","link","symlink","self-reference"],"backgroundTag":"invalid-argument-value","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}