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

  1. Pass --yes if you intentionally want to overwrite the non-empty directory.
  2. Choose an empty or new target directory for the install.
  3. Delete or clear the existing directory contents first if they are no longer needed.
  4. 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

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


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/467800e1e0e2859a. Report an issue: GitHub.