jdx/mise · error · eyre::Report
target is not the managed directory, use --force to remove i
Error message
target is not the managed directory, use --force to remove it
What it means
For `symlink-each` entries (mise recreates the source directory's structure under the target and symlinks each file individually), the target must be a real directory that mise seeded. If the target itself is a symlink or an existing non-directory file, mise cannot enumerate owned children and refuses removal without `--force`.
Source
Thrown at src/system/files.rs:1556
"target symlink points to {}, use --force to remove it",
dest.display_user()
);
}
} else if req.target.exists() {
if opts.force {
paths.insert(req.target.clone(), ());
} else {
bail!("target is not the managed symlink, use --force to remove it");
}
}
}
FileMode::SymlinkEach if !cfg!(windows) => {
clear_symlink_each_state = symlink_each_state_path(req).exists();
if req.target.is_symlink() || (req.target.exists() && !req.target.is_dir()) {
if opts.force {
paths.insert(req.target.clone(), ());
} else {
bail!("target is not the managed directory, use --force to remove it");
}
} else if req.target.is_dir() {
for path in owned_links(req)? {
paths.insert(path, ());
}
cleanup_empty_dirs = true;
}
}
FileMode::Copy | FileMode::SymlinkEach if req.source.is_dir() => {
if req.target.is_symlink() || (req.target.exists() && !req.target.is_dir()) {
if opts.force {
paths.insert(req.target.clone(), ());
} else {
bail!("target is not the managed directory, use --force to remove it");
}
} else if req.target.is_dir() {
for (source, target) in walk_source_files(req)? {
plan_regular_file(&source, &target, opts.force, &mut paths)?;View on GitHub (pinned to 6f52dcdf99)
Solutions
- Restore the target to a plain directory (remove the replacement, `mkdir`), re-apply, then unapply
- Use `--force` if the replacement symlink/file is disposable
- Fix the entry's mode/source in mise.toml if it was misdeclared for this target
Example fix
# before: ~/.config/ghostty was replaced by a symlink $ ls -ld ~/.config/ghostty lrwxrwxrwx 1 me me 22 ~/.config/ghostty -> /home/me/dotfiles/ghostty $ mise bootstrap dotfiles unapply Error: target is not the managed directory, use --force to remove it # after: keep the checkout elsewhere, restore a real dir, re-apply, unapply $ rm ~/.config/ghostty && mkdir ~/.config/ghostty $ mise bootstrap dotfiles apply && mise bootstrap dotfiles unapply
Defensive patterns
Strategy: validation
Validate before calling
# symlink-each targets must be plain directories.
[ -L ~/.config/ghostty ] && { echo 'target is a symlink'; exit 1; }
[ -e ~/.config/ghostty ] && [ ! -d ~/.config/ghostty ] && { echo 'target not a dir'; exit 1; } Type guard
fn is_not_managed_dir(err: &miette::Report) -> bool {
err.to_string()
.starts_with("target is not the managed directory")
} Prevention
- Never replace symlink-each target directories with links; add an ignore entry instead
- Run `mise bootstrap dotfiles status` after manual target surgery
- Prefer `symlink` mode for whole-directory dotfiles when you do not need foreign files inside the target
When it happens
Trigger: `unapply` of a `mode = "symlink-each"` entry (non-Windows) where `req.target.is_symlink()` or the target exists and is not a directory — e.g. ~/.config/foo was replaced by a symlink to a dotfiles checkout, or turned into a file.
Common situations: User replaced the target directory with a symlink to save space; the directory was converted to a file; entry mode changed from symlink to symlink-each without re-apply.
Related errors
- cannot verify {}; use --force to remove it
- no dotfiles matched target filter: {}
- files: cannot unapply these entries:\n{}
- target symlink points to {}, use --force to remove it
- target is not the managed symlink, use --force to remove it
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/27a113f1e53e0415.
Report an issue: GitHub.