jdx/mise · error
refusing to overwrite non-empty directory
Error message
refusing to overwrite non-empty directory {}; pass {} or choose an empty/new path What it means
This error is thrown by the install-into command when the target install directory exists, is non-empty, and the user has not confirmed proceeding (no --yes and declined the interactive prompt). It protects against clobbering an existing tool installation directory with a new install.
Solutions
- Re-run with --yes to confirm overwriting the non-empty directory
- Remove or move the existing directory contents first, or choose an empty/new install path
- In CI, pre-clean the target directory (rm -rf) before installing
Example fix
// before mise install-into node 22.0.0 ~/.local/share/mise/installs/node/22.0.0 // after mise install-into node 22.0.0 ~/.local/share/mise/installs/node/22.0.0 --yes
Defensive patterns
Strategy: validation
Validate before calling
INSTALL_PATH="$HOME/.local/share/mise/installs/node/22.0.0" if [[ -d "$INSTALL_PATH" ]] && [[ -n "$(ls -A "$INSTALL_PATH" 2>/dev/null)" ]]; then rm -rf "$INSTALL_PATH" # or pass --yes to mise install-into fi
Prevention
- Pre-clean install target directories in CI before installing
- Pass --yes deliberately only when overwriting is intended
- Use fresh/empty install paths for reproducible installs
When it happens
Trigger: Running `mise install-into` into a directory that already contains files, in a non-interactive context (or after answering 'no' at the prompt) without passing --yes.
Common situations: Re-running an install into a previously populated install dir; CI scripts hitting a stale directory from an earlier run; pointing install path at a shared or versioned directory that already has content.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- is not a mise bin. Perhaps you need to install it first.
- @ is not installed hint: run `mise install @ `, or `mise ls…
- @ is not installed hint: run `mise install @ `, or `mise ls…
- a branch name is required
- a glob is required
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/467800e1e0e2859a.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli/install_into.rs:153
// already exists at the install path. Check immediately before the
// install performs that deletion (rather than at the start of `run`) so
// a directory that became non-empty during tool resolution can't be
// clobbered without an explicit opt-in. Refuse to overwrite a non-empty
// directory (e.g. `.`) unless the user passes -y/--yes or confirms
// interactively; the prompt defaults to "no" since it is destructive.
// (#8115)
if path_has_contents(&install_path) {
let proceed = Settings::get().yes
|| prompt::confirm_with_default(
format!(
"{} is not empty; install-into will delete its contents. Continue?",
display_path(&install_path)
),
false,
)?
.is_yes();
if !proceed {
bail!(
"refusing to overwrite non-empty directory {}; pass {} or choose an empty/new path",
display_path(&install_path),
style("--yes").yellow().for_stderr()
);
}
}
backend.install_version(install_ctx, tv).await?;
Ok(())
}
}
/// Replacement deletes the destination, so one that overlaps the lock directory
/// in either direction is refused: an ancestor would take the whole directory
/// with it, and a descendant could unlink an active lock file, letting the next
/// process create a replacement and install alongside the holder.
fn lock_dir_overlap(destination: &Path, lock_dir: &Path) -> eyre::Report {
eyre!(
"install-into destination {} overlaps mise's lock directory {}; choose a different destination",View on GitHub (pinned to 533346cc37)