{"record":{"id":"c24905f7b272248a","repo":"jdx/mise","slug":"target-is-not-the-managed-symlink-use-force-to","errorCode":null,"errorMessage":"target is not the managed symlink, use --force to remove it","messagePattern":"target is not the managed symlink, use --force to remove it","errorType":"exception","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/files.rs","lineNumber":1546,"sourceCode":"        FileMode::Symlink\n            if !(cfg!(windows) && req.source.is_file() && !req.target.is_symlink()) =>\n        {\n            if req.target.is_symlink() {\n                let dest = std::fs::read_link(&req.target)?;\n                if opts.force || dest == req.source || points_at_same_file(&req.target, &req.source)\n                {\n                    paths.insert(req.target.clone(), ());\n                } else {\n                    bail!(\n                        \"target symlink points to {}, use --force to remove it\",\n                        dest.display_user()\n                    );\n                }\n            } else if req.target.exists() {\n                if opts.force {\n                    paths.insert(req.target.clone(), ());\n                } else {\n                    bail!(\"target is not the managed symlink, use --force to remove it\");\n                }\n            }\n        }\n        FileMode::SymlinkEach if !cfg!(windows) => {\n            clear_symlink_each_state = symlink_each_state_path(req).exists();\n            if req.target.is_symlink() || (req.target.exists() && !req.target.is_dir()) {\n                if opts.force {\n                    paths.insert(req.target.clone(), ());\n                } else {\n                    bail!(\"target is not the managed directory, use --force to remove it\");\n                }\n            } else if req.target.is_dir() {\n                for path in owned_links(req)? {\n                    paths.insert(path, ());\n                }\n                cleanup_empty_dirs = true;\n            }\n        }","sourceCodeStart":1528,"sourceCodeEnd":1564,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/system/files.rs#L1528-L1564","documentation":"A `symlink`-mode entry's target exists but is a regular file or directory rather than a symlink, so mise has no ownership evidence (a real file may hold user data) and refuses removal unless `--force` is given.","triggerScenarios":"`unapply` where the target exists (`req.target.exists()`) but `is_symlink()` is false — the link was replaced by a real file (some editors 'unlink and save'), or the entry previously ran in copy/content mode and the mode was switched to symlink without re-apply.","commonSituations":"Editor replaced the symlink with a copy of the file; user did `cp realfile ~/.gitconfig` over the link; mode churn in mise.toml without a re-apply in between.","solutions":["Back up any wanted edits (`cp ~/.gitconfig ~/gitconfig.bak`), then re-run with `--force`","Or restore mise ownership first: `mise bootstrap dotfiles apply` recreates the symlink, after which unapply verifies normally","Merge hand edits back into the dotfiles source before forcing"],"exampleFix":"# before: target is a real file, not the managed symlink\n$ ls -l ~/.gitconfig\n-rw-r--r-- 1 me me 412 ~/.gitconfig\n$ mise bootstrap dotfiles unapply\nError: target is not the managed symlink, use --force to remove it\n\n# after: keep edits, then force-remove\n$ cp ~/.gitconfig ~/gitconfig.bak && git -C ~/dotfiles diff  # salvage edits\n$ mise bootstrap dotfiles unapply --force","handlingStrategy":"validation","validationCode":"# Fail early when a symlink-mode target is not a symlink.\nfor t in ~/.gitconfig ~/.vimrc; do\n  [ -e \"$t\" ] && [ ! -L \"$t\" ] && echo \"NOT A SYMLINK: $t\" && exit 1\ndone","typeGuard":"fn is_not_managed_symlink(err: &miette::Report) -> bool {\n    err.to_string()\n        .starts_with(\"target is not the managed symlink\")\n}","tryCatchPattern":null,"preventionTips":["Configure editors to follow symlinks on save (e.g. vim 'writebackup' settings) instead of replacing them","After switching an entry's mode, always re-apply before unapplying","Check `ls -l` on managed targets periodically to spot replaced links"],"tags":["mise","dotfiles","symlink","file-type","unapply"],"backgroundTag":"unexpected-file-type","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T20:17:18.057Z"}