jdx/mise · error

existing file conflicts with adoption

Error message

existing file conflicts with adoption: {entry}

What it means

During adoption of a non-empty destination, mise refuses to replace existing files. If a tracked entry already exists in the destination and either the source entry is itself a symlink, the existing path is not a regular file, or the file contents differ byte-for-byte from the checkout copy, adoption aborts. Existing files are never overwritten; only new files and Git metadata are moved.

Solutions

  1. Compare and reconcile: `diff <destination>/<entry> <expected-content>`, then either update the destination file to match the repo or remove it so adoption can move the repo's copy in.
  2. Back up your version and delete the destination file: `mv <entry> <entry>.bak`, then retry the install.
  3. Commit your destination version into the source repository first (via the normal config workflow) so the contents match.
  4. If the existing path is a directory where a file should be, remove or rename it, then retry.

Example fix

// before
$ diff ~/.config/mise/settings.toml repo-copy/settings.toml
differ

// after
$ mv ~/.config/mise/settings.toml ~/.config/mise/settings.toml.bak
// retry install; adopt repo copy, merge .bak changes back afterwards
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
for (const entry of trackedFiles) {
  const p = dest + '/' + entry;
  if (fs.existsSync(p) && !fs.statSync(p).isFile()) throw new Error('non-file blocks adoption: ' + p);
}

Try / catch

try {
  await installSource(bundle, origin);
} catch (e) {
  if (/conflicts with adoption/.test(String(e.cause ?? e))) {
    console.error('diff the listed file, back it up, and remove it so the repo copy can be moved in');
  }
  throw e;
}

Prevention

When it happens

Trigger: install/install_source/preview_source (install_at) into a non-empty directory without `.git`, where a file with the same tracked path exists in the destination but has different content, is a directory/fifo instead of a regular file, or the source copy is a symlink.

Common situations: User already has their own `settings.toml` with different content; a stale directory occupies a path the repo expects to be a file; the source repo symlinked a config file (which mise does not adopt).

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


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/8907e75a32f8a7b4. Report an issue: GitHub.

Appendix: source

Thrown at src/system/remote_repository.rs:338

        return Ok(destination.to_path_buf());
    }
    let nonempty = destination.exists() && destination.read_dir()?.next().is_some();
    if nonempty {
        for entry in entries.split('\0').filter(|s| !s.is_empty()) {
            let mut ancestor = destination.to_path_buf();
            for component in Path::new(entry).components() {
                ancestor.push(component);
                if ancestor.is_symlink() {
                    bail!("existing symbolic link conflicts with adoption: {entry}");
                }
            }
            let existing = destination.join(entry);
            if existing.exists()
                && (checkout.join(entry).is_symlink()
                    || !existing.is_file()
                    || std::fs::read(&existing)? != std::fs::read(checkout.join(entry))?)
            {
                bail!("existing file conflicts with adoption: {entry}");
            }
        }
        if dry_run {
            let new_files = entries
                .split('\0')
                .filter(|s| !s.is_empty())
                .filter(|entry| !destination.join(entry).exists())
                .count();
            miseprintln!(
                "Would adopt {shown} as the global configuration repository ({new_files} new file(s); existing files and local overrides preserved)"
            );
            return Ok(destination.to_path_buf());
        }
        eprintln!(
            "Adopt existing global configuration at {} (preserving existing files and local overrides)",
            destination.display()
        );
        if !yes

View on GitHub (pinned to 533346cc37)