{"record":{"id":"479cf3a03571cbaf","repo":"uutils/coreutils","slug":"mv-error-directory-not-empty","errorCode":null,"errorMessage":"mv-error-directory-not-empty","messagePattern":"mv-error-directory-not-empty","errorType":"error_code","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"src/uu/mv/src/mv.rs","lineNumber":876,"sourceCode":"            // For backup renames, we don't need to track hardlinks as we're just moving the existing file\n            rename_with_fallback(to, backup_path, display_manager, false, None, None)?;\n        }\n    }\n\n    // \"to\" may no longer exist if it was backed up\n    // `symlink_metadata` does not follow symlinks, so a symlink to a directory\n    // is not reported as a directory, as with the previous\n    // `to.exists() && to.is_dir() && !to.is_symlink()` check\n    if to\n        .symlink_metadata()\n        .is_ok_and(|metadata| metadata.is_dir())\n    {\n        // normalize behavior between *nix and windows\n        if from.is_dir() {\n            if is_empty_dir(to) {\n                fs::remove_dir(to)?;\n            } else {\n                return Err(io::Error::new(\n                    io::ErrorKind::DirectoryNotEmpty,\n                    translate!(\"mv-error-directory-not-empty\"),\n                ));\n            }\n        }\n    }\n\n    #[cfg(unix)]\n    {\n        rename_with_fallback(\n            from,\n            to,\n            display_manager,\n            opts.verbose,\n            hardlink_tracker,\n            hardlink_scanner,\n        )?;\n    }","sourceCodeStart":858,"sourceCodeEnd":894,"githubUrl":"https://github.com/uutils/coreutils/blob/92995feca29e324a7c559ede91db81c32d9f5d59/src/uu/mv/src/mv.rs#L858-L894","documentation":"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.","triggerScenarios":"`mv src_dir existing_nonempty_dir` where the destination exists and contains entries, causing the pre-rename cleanup path to refuse.","commonSituations":"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.","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`"],"exampleFix":"// before\nmv newlib ~/proj/lib   # lib exists and is non-empty\n// after\nrm -rf ~/proj/lib && mv newlib ~/proj/lib","handlingStrategy":"validation","validationCode":"if [ -d \"$dest\" ] && [ -n \"$(ls -A \"$dest\")\" ]; then echo \"dest not empty\" >&2; exit 1; fi","typeGuard":"fn is_empty_dir(p: &Path) -> bool {\n    std::fs::read_dir(p).map(|mut d| d.next().is_none()).unwrap_or(true)\n}","tryCatchPattern":"match mv_result {\n    Err(e) if e.to_string().contains(\"directory not empty\") => {\n        eprintln!(\"merge contents manually or clear the destination first\");\n    }\n    r => r?,\n}","preventionTips":["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"],"tags":["mv","directory","cli"],"backgroundTag":"directory-not-empty","analyzedSha":"92995feca29e324a7c559ede91db81c32d9f5d59","analyzedAt":"2026-09-20T12:39:35.476Z","contentChangedAt":"2026-09-20T12:39:35.476Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}