jdx/mise · error
refusing to overwrite non-empty directory {}; pass {} or cho
Error message
refusing to overwrite non-empty directory {}; pass {} or choose an empty/new path What it means
`mise install <tool>@<version> <path>` (install_into) refuses to install into a non-empty directory by default, to avoid clobbering existing files. The user is prompted to confirm; without a TTY/confirmation (or if they decline) mise bails, suggesting --yes to proceed.
Source
Thrown at src/cli/install_into.rs:152
// 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 afd2eddd3a)
Solutions
- Pass --yes if you intentionally want to overwrite the non-empty directory.
- Choose an empty or new target directory for the install.
- Delete or clear the existing directory contents first if they are no longer needed.
- In CI, decide explicitly: either pre-clean the directory or add --yes to the command.
Example fix
// before (fails on non-empty dir, non-interactive) mise install node@20.0.0 ~/.nodes/20.0.0 // after mise install --yes node@20.0.0 ~/.nodes/20.0.0
Defensive patterns
Strategy: validation
Validate before calling
# shell: ensure target dir is empty (or absent) before non-interactive install if [ -d "$DIR" ] && [ -n "$(ls -A "$DIR")" ]; then echo "refusing: $DIR not empty"; exit 1; fi mise install node@20.0.0 "$DIR"
Prevention
- Pre-clean or choose a fresh directory before installing into an explicit path.
- In CI/non-interactive contexts, always pass --yes deliberately or pre-validate emptiness.
- Never reuse old version directories for new installs.
When it happens
Trigger: Running `mise install <tool>@<version> <existing-dir>` where the target install_path already contains files and neither an affirmative interactive confirmation nor the --yes flag is provided.
Common situations: Re-running an install into a previously populated directory; scripting/CI where there is no TTY so the prompt cannot be answered; re-using an old version directory by mistake.
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
- {}@{requested} is not installed{resolved} hint: run `mise in
- cannot link {} to its own install path
- No executable found for configured tool: {bin_name} The inst
- {bin_name} is a mise bin however it is not currently active.
- Ruby engine '{}' is not supported on Windows. Only standard
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/467800e1e0e2859a.
Report an issue: GitHub.