{"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":"io::Error","httpStatus":null,"severity":"error","filePath":"src/uu/mv/src/mv.rs","lineNumber":864,"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":846,"sourceCodeEnd":882,"githubUrl":"https://github.com/uutils/coreutils/blob/85295bbf788bfd7a6926ba692031563504b304b7/src/uu/mv/src/mv.rs#L846-L882","documentation":"When the destination of a rename exists and is a non-empty directory, mv removes an empty target dir but otherwise cannot proceed, returning ErrorKind::DirectoryNotEmpty with this message. This normalizes behavior between Unix and Windows so mv never silently merges directories. On Unix the kernel would raise ENOTEMPTY; here it is raised explicitly.","triggerScenarios":"`mv src_dir dest_dir` where dest_dir exists, is a directory, and still contains entries — the rename syscall cannot replace a non-empty directory.","commonSituations":"Retrying a move after a previous partial copy left files in the destination; merging project folders by accident; scripts assuming mv merges directories like `cp -r` semantics.","solutions":["Empty or remove the destination first: `rm -rf dest_dir` if its contents are disposable, then re-run mv","Explicitly merge with `cp -a src/. dest/ && rm -rf src` or rsync --remove-source-files if merging is intended","Move into the directory instead: `mv src_dir/* dest_dir/` when merging is desired","Inspect dest_dir contents before deciding which files to keep"],"exampleFix":"// before\nmv newcfg/ /etc/myapp/\n// after\nrsync -a --remove-source-files newcfg/ /etc/myapp/ && rmdir newcfg\n# or, if disposable:\nrm -rf /etc/myapp && mv newcfg/ /etc/myapp/","handlingStrategy":"validation","validationCode":"# before moving dir onto existing dir\nif [ -d \"$dest\" ] && [ -n \"$(ls -A \"$dest\")\" ]; then\n  echo \"dest not empty; merge or remove first\"; exit 1\nfi","typeGuard":null,"tryCatchPattern":"null","preventionTips":["Check destination directory contents before directory moves","Use rsync --remove-source-files for merge semantics instead of mv","Clean up partial previous transfers before retrying a move"],"tags":["mv","directory","not-empty","rename"],"backgroundTag":"directory-not-empty","analyzedSha":"85295bbf788bfd7a6926ba692031563504b304b7","analyzedAt":"2026-08-31T11:11:36.175Z","contentChangedAt":"2026-08-31T11:11:36.175Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}