{"record":{"id":"d2c4eef3a6f4b23f","repo":"uutils/coreutils","slug":"mv-error-backup-might-destroy-source","errorCode":null,"errorMessage":"mv-error-backup-might-destroy-source","messagePattern":"mv-error-backup-might-destroy-source","errorType":"error_code","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"src/uu/mv/src/mv.rs","lineNumber":381,"sourceCode":"    }\n}\n\nfn parse_paths(files: &[OsString], opts: &Options) -> Vec<PathBuf> {\n    let paths = files.iter().map(Path::new);\n\n    if opts.strip_slashes {\n        paths\n            .map(|p| p.components().as_path().to_owned())\n            .collect::<Vec<PathBuf>>()\n    } else {\n        paths.map(ToOwned::to_owned).collect::<Vec<PathBuf>>()\n    }\n}\n\nfn handle_two_paths(source: &Path, target: &Path, opts: &Options) -> UResult<()> {\n    // `mv` never follows a symlink source, so the guard must not either.\n    if backup_would_destroy_source(source, target, &opts.suffix, opts.backup, false) {\n        return Err(io::Error::new(\n            io::ErrorKind::NotFound,\n            translate!(\"mv-error-backup-might-destroy-source\", \"target\" => target.quote(), \"source\" => source.quote()),\n        )\n        .into());\n    }\n    let Ok(source_metadata) = source.symlink_metadata() else {\n        return Err(if path_ends_with_terminator(source) {\n            MvError::CannotStatNotADirectory(source.quote().to_string()).into()\n        } else {\n            MvError::NoSuchFile(source.quote().to_string()).into()\n        });\n    };\n\n    // `symlink_metadata` does not follow symlinks, so this is equivalent to\n    // `source.is_dir() && !source.is_symlink()` without the extra `stat` calls.\n    let source_is_dir = source_metadata.is_dir();\n    let target_is_dir = match target.symlink_metadata() {\n        Ok(metadata) if metadata.is_symlink() => fs::canonicalize(target).is_ok_and(|p| p.is_dir()),","sourceCodeStart":363,"sourceCodeEnd":399,"githubUrl":"https://github.com/uutils/coreutils/blob/85295bbf788bfd7a6926ba692031563504b304b7/src/uu/mv/src/mv.rs#L363-L399","documentation":"mv refuses to perform the move when creating the requested backup would overwrite (destroy) the source itself. backup_would_destroy_source detects that the backup target name — destination plus backup suffix — resolves to the source file, so proceeding would clobber the input. It returns NotFound with this message quoting both target and source.","triggerScenarios":"mv --backup (or -b with a suffix/VAR) where source and dest are the same file via different paths or the backup name equals the source path, e.g., `mv --suffix=.orig a a.orig` styles of invocations or hardlink/symlink aliasing between source and backup target.","commonSituations":"Scripts that build backup suffixes from variables which collide with the source name; moving a file onto a path whose backup suffix name points back at the same inode (hardlink); typos where source and target differ only by the backup suffix.","solutions":["Change the backup suffix (--suffix=SFX or VERSION_CONTROL) so the backup name does not equal the source path","Check whether source and target are the same file (same inode) with `ls -i` and fix the script's path construction","Drop --backup/-b if no backup is actually needed","Quote/normalize paths in scripts to avoid aliasing through symlinks or hardlinks"],"exampleFix":"// before\nmv --suffix=.bak notes.txt notes.txt.bak   # backup name == ...\n// after\nmv --suffix=.old notes.txt notes.txt.bak","handlingStrategy":"validation","validationCode":"# ensure backup name does not collide with the source\nif [ \"$target$suffix\" = \"$source\" ] || [ -e \"$target$suffix\" ] && [ \"$target$suffix\" -ef \"$source\" ]; then\n  echo \"backup would destroy source\"; exit 1\nfi","typeGuard":null,"tryCatchPattern":"null","preventionTips":["Never derive backup suffixes that equal the source filename","Check inode equality (ls -i / stat) when paths may alias via hardlinks","Sanitize path variables in scripts before mv with --backup"],"tags":["mv","backup","file-overwrite"],"backgroundTag":"backup-would-destroy-source","analyzedSha":"85295bbf788bfd7a6926ba692031563504b304b7","analyzedAt":"2026-08-31T11:11:36.175Z","contentChangedAt":"2026-08-31T11:11:36.175Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}