jdx/mise · error
cannot link {name}: these files already exist and were not c
Error message
cannot link {name}: these files already exist and were not created by mise or brew:
{}
Remove or rename them, then re-run `mise bootstrap packages apply` What it means
When linking a keg into the brew prefix, pour checks each target path; if a file or symlink already exists that was not created by mise or brew, it refuses to link and lists the conflicting paths. Nothing has been linked yet — the caller rolls the keg back — so the error lists files to remove and the exact command to re-run.
Source
Thrown at src/system/packages/brew/pour.rs:597
let dest = prefix_path.join(rel);
if !can_overwrite(&dest) {
conflicts.push(dest);
} else {
links.push((dest, entry.path().to_path_buf()));
}
}
}
let linked = prefix::linked_keg_record(name);
if can_overwrite(&linked) {
links.push((linked, keg.clone()));
} else {
conflicts.push(linked);
}
}
if !conflicts.is_empty() {
// nothing has been linked yet, and the caller rolls the keg back on
// this error — so don't claim it remains usable
bail!(
"cannot link {name}: these files already exist and were not created by mise or brew:\n{}\n\
Remove or rename them, then re-run `mise bootstrap packages apply`",
conflicts
.iter()
.map(|p| format!(" {}", p.display()))
.collect::<Vec<_>>()
.join("\n"),
);
}
// remember every symlink we overwrite (upgrades replace the previous
// version's links, opt included) so a failed link restores all of them
let mut created: Vec<PathBuf> = vec![];
let mut replaced: Vec<(PathBuf, PathBuf)> = vec![];
let mut failure: Option<eyre::Report> = None;
for (dest, target) in &links {
let made = (|| -> Result<()> {
// a parent that is a brew directory symlink must become a real
// directory first — otherwise the link below would be createdView on GitHub (pinned to afd2eddd3a)
Solutions
- Remove or rename the listed conflicting files/symlinks yourself
- Re-run `mise bootstrap packages apply`
- If a conflicting symlink points into another Cellar keg, uninstall or relink that keg first
- Verify ownership before deleting system-wide files
Example fix
# before ls -l /home/linuxbrew/.linuxbrew/bin/tool # foreign symlink rm /home/linuxbrew/.linuxbrew/bin/tool # after mise bootstrap packages apply
Defensive patterns
Strategy: validation
Validate before calling
const conflicts = kegPaths.filter(p => fs.existsSync(p) && !createdByMiseOrBrew(p));
if (conflicts.length) console.error('remove or rename:', conflicts); Try / catch
catch (e) {
if (String(e).startsWith('cannot link')) {
const files = e.message.split('\n').filter(l => l.startsWith(' ')).map(l => l.trim());
files.forEach(f => fs.renameSync(f, f + '.bak'));
return retryApply();
}
throw e;
} Prevention
- Uninstall manually installed copies of tools before switching to brew via mise
- Inspect <prefix>/bin for foreign symlinks before running packages apply
- Use one package manager per tool
When it happens
Trigger: Running `mise bootstrap packages apply` on a machine where a manually installed copy of the tool (make install, a different package manager, hand-placed symlinks) already occupies files under the brew prefix that link_keg would create.
Common situations: Switching from manual source installs to brew bottles; leftovers from a previous tool manager that used different markers; a stale symlink pointing outside the Cellar; another keg owns a shared directory.
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
- brew-cask: completion target '{}' already exists and is not
- [dotfiles]."{}": mode symlink-each requires a directory sour
- brew-cask: staged symlink path escaped extraction root: {}
- brew-cask: refusing generic artifact source outside the extr
- brew-cask: refusing to restore flight target through a chang
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/85fe2573bfc55570.
Report an issue: GitHub.