uutils/coreutils · error · std::io::Error
mv-error-directory-not-empty
Error message
mv-error-directory-not-empty
What it means
When `rename` must move a directory onto an existing path, it removes an empty target directory; if the target is a non-empty directory it cannot proceed and raises `ErrorKind::DirectoryNotEmpty` with this message. This normalizes behavior between Unix (where rename(2) fails with ENOTEMPTY) and Windows.
Solutions
- Remove or empty the destination directory first (`rm -rf dest`)
- Use `mv src/* dest/` or `rsync -a src/ dest/ && rm -rf src` to merge contents instead
- Pass a fresh destination path that does not exist
- Script a check: `if [ -d dest ] && [ -n "$(ls -A dest)" ]; then merge; fi`
Example fix
// before mv newlib ~/proj/lib # lib exists and is non-empty // after rm -rf ~/proj/lib && mv newlib ~/proj/lib
Defensive patterns
Strategy: validation
Validate before calling
if [ -d "$dest" ] && [ -n "$(ls -A "$dest")" ]; then echo "dest not empty" >&2; exit 1; fi
Type guard
fn is_empty_dir(p: &Path) -> bool {
std::fs::read_dir(p).map(|mut d| d.next().is_none()).unwrap_or(true)
} Try / catch
match mv_result {
Err(e) if e.to_string().contains("directory not empty") => {
eprintln!("merge contents manually or clear the destination first");
}
r => r?,
} Prevention
- Check destination contents before directory moves
- Remember mv never merges directories; use rsync for that
- Use fresh destination paths in automation
- Add pre-flight checks in deployment scripts
When it happens
Trigger: `mv src_dir existing_nonempty_dir` where the destination exists and contains entries, causing the pre-rename cleanup path to refuse.
Common situations: Moving a project folder onto an already-populated folder, scripts assuming mv merges directories (it does not), or leftover build/output directories in the destination.
Related errors
- mv-error-backup-might-destroy-source
- mv-error-dangling-symlink
- could not allocate a unique temp name in destination…
- invalid destination path
- invalid value
AI-assisted analysis of uutils/coreutils@92995feca2 (2026-09-20).
Data as JSON: /api/errors/479cf3a03571cbaf.
Report an issue: GitHub.
Appendix: source
Thrown at src/uu/mv/src/mv.rs:876
// For backup renames, we don't need to track hardlinks as we're just moving the existing file
rename_with_fallback(to, backup_path, display_manager, false, None, None)?;
}
}
// "to" may no longer exist if it was backed up
// `symlink_metadata` does not follow symlinks, so a symlink to a directory
// is not reported as a directory, as with the previous
// `to.exists() && to.is_dir() && !to.is_symlink()` check
if to
.symlink_metadata()
.is_ok_and(|metadata| metadata.is_dir())
{
// normalize behavior between *nix and windows
if from.is_dir() {
if is_empty_dir(to) {
fs::remove_dir(to)?;
} else {
return Err(io::Error::new(
io::ErrorKind::DirectoryNotEmpty,
translate!("mv-error-directory-not-empty"),
));
}
}
}
#[cfg(unix)]
{
rename_with_fallback(
from,
to,
display_manager,
opts.verbose,
hardlink_tracker,
hardlink_scanner,
)?;
}View on GitHub (pinned to 92995feca2)