jdx/mise · error
existing file conflicts with adoption: {entry}
Error message
existing file conflicts with adoption: {entry} What it means
During adoption of a non-empty destination (no `.git`), install_at compares each transferred file with any existing file at the same relative path. Adoption only proceeds when the existing file is a regular file with byte-identical content and the transferred entry is not itself a symlink; anything else — differing content, a directory in the way, or a symlink on either side — aborts the adoption. This guarantees adoption never overwrites or clobbers user data.
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 !yesView on GitHub (pinned to afd2eddd3a)
Solutions
- Diff the conflicting files (`diff <destination>/<entry> <source-repo>/<entry>`) and reconcile them in the source repository, then re-transfer.
- If the local version should win, copy it into the source repo, commit, and regenerate the bundle so contents match.
- If the transferred version should win, back up and remove the differing local file before retrying.
- Remove unrelated stale files/directories that occupy transferred entry paths (e.g. leftover directories where the transfer expects a file).
Example fix
// before: existing config.toml differs from transferred one diff ~/.config/mise/config.toml ./source/config.toml # reconcile edits in the source repo, commit, then: cp ./source/config.toml ~/.config/mise/config.toml // after: files are byte-identical; adoption succeeds
Defensive patterns
Strategy: validation
Validate before calling
const { execFileSync } = require('child_process');
const entries = execFileSync('git', ['-C', checkout, 'ls-tree', '-r', '--name-only', 'HEAD']).toString().split('\n');
for (const e of entries.filter(Boolean)) {
const existing = path.join(dest, e);
if (fs.existsSync(existing) && !fs.statSync(existing).isFile()) throw new Error(`conflict at ${e}`);
if (fs.existsSync(existing) && !fs.readFileSync(existing).equals(fs.readFileSync(path.join(checkout, e)))) throw new Error(`content differs at ${e}`);
} Prevention
- Preview the adoption (dry run) before executing it.
- Keep local overrides in `*.local.toml` files rather than editing tracked files.
- Reconcile divergent copies by committing local content into the source repo before transferring.
When it happens
Trigger: Installing into an existing non-empty directory where `destination/<entry>` already exists and differs from the checkout's version: different bytes, existing path is a directory, or the transferred (or existing) entry is a symlink.
Common situations: User already has their own config.toml with different settings at the destination; a previous partial adoption left files behind that have since been edited; the source repo gained a symlink where the user has a real file.
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 an existing repository without the mise marker; `mise
- remote task path is not a regular file or directory: {}
- cannot encode #{value.class} as JSON
- rename_exe: cannot rename '{}' to '{}': target already exist
- git command failed with {status}
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/8907e75a32f8a7b4.
Report an issue: GitHub.