jdx/mise · error · eyre::Report
refusing to replace non-directory path
Error message
refusing to replace non-directory path: {} What it means
When creating a managed directory, the library stats the target path. If it exists as a non-directory (regular file, symlink to file, etc.) and `replace` was not requested, it refuses with this error rather than silently deleting a file to make room for a directory.
Solutions
- Set `replace: true` so the library removes the file before creating the directory
- Delete the conflicting file manually and re-run
- Fix the manifest path so it no longer collides with an existing file
Example fix
// before
create_managed_dir(Path::new("/etc/app/conf.d"), ReplaceMode::Keep)?; // a file exists there
// after
create_managed_dir(Path::new("/etc/app/conf.d"), ReplaceMode::Replace)?; Defensive patterns
Strategy: validation
Validate before calling
fn check_dir_target(path: &std::path::Path, replace: bool) -> Result<(), String> {
match std::fs::metadata(path) {
Err(_) => Ok(()),
Ok(m) if m.is_dir() => Ok(()),
Ok(_) if replace => Ok(()),
Ok(_) => Err(format!("{} exists as a file; pass replace", path.display())),
}
} Type guard
fn target_is_dir_or_absent(path: &std::path::Path) -> bool {
std::fs::metadata(path).map_or(true, |m| m.is_dir())
} Try / catch
match result {
Err(e) if e.to_string().contains("refusing to replace non-directory") => {
std::fs::remove_file(path)?; // after verifying the file is expendable
retry_operation()?;
}
other => other?,
} Prevention
- Remove stale files that share names with manifest directories
- Verify path kinds after tool upgrades or manifest edits
- Run a reconciliation pass before managed-directory creation
When it happens
Trigger: Calling create managed directory with `replace: false` on a path occupied by a regular file — e.g. manifest defines directory "/etc/app/conf.d" but a stale file named "conf.d" exists.
Common situations: Path kind changed between tool versions or manifest edits; a file was accidentally created with the directory's name; leftover artifacts from a failed prior run.
Related errors
- cannot be recreated as a directory: something else is there…
- directory ' ' cannot be present while managed parent ' ' is…
- refusing to replace non-file path
- a parent directory is now a symlink; left untouched
- app Info.plist must be a regular file
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/dc5bb1db46e40537.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/managed_files.rs:1603
path: &Path,
owner: Option<&str>,
group: Option<&str>,
mode: u32,
replace: bool,
) -> Result<()> {
match fs::symlink_metadata(path) {
Err(error)
if matches!(
error.kind(),
std::io::ErrorKind::NotFound | std::io::ErrorKind::NotADirectory
) => {}
Err(error) => {
return Err(error)
.wrap_err_with(|| format!("failed to inspect directory {}", path.display()));
}
Ok(metadata) if metadata.file_type().is_dir() => {}
Ok(_) if !replace => {
bail!("refusing to replace non-directory path: {}", path.display())
}
Ok(_) => {
fs::remove_file(path).wrap_err_with(|| {
format!(
"failed to remove existing path before creating directory {}",
path.display()
)
})?;
}
}
#[cfg(unix)]
{
let directory = open_or_create_directory_tree(path)
.wrap_err_with(|| format!("failed to create directory {}", path.display()))?;
set_directory_metadata(&directory, owner, group, mode)
.wrap_err_with(|| format!("failed to set metadata on directory {}", path.display()))
}View on GitHub (pinned to 533346cc37)