{"record":{"id":"839506a9099b34f7","repo":"uutils/coreutils","slug":"invalid-destination-path","errorCode":null,"errorMessage":"invalid destination path","messagePattern":"invalid destination path","errorType":"error_code","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"src/uu/mv/src/mv.rs","lineNumber":1075,"sourceCode":"#[cfg(all(unix, not(target_os = \"redox\")))]\nfn create_symlink_replace(target: &Path, to: &Path) -> io::Result<()> {\n    use io::Read;\n    use rustix::fs::{AtFlags, CWD, Mode, OFlags, openat, renameat, symlinkat, unlinkat};\n    use std::ffi::OsStr;\n    use std::os::unix::ffi::OsStrExt;\n\n    // GNU's template is `CuXXXXXX`: a 2-char prefix plus 6 random chars\n    // drawn from a 62-char alphabet. Modulo bias on a 256→62 mapping is\n    // ~3% per slot — irrelevant for an 8-char unguessability budget.\n    const ALPHABET: &[u8; 62] = b\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\n    let parent = to\n        .parent()\n        .filter(|p| !p.as_os_str().is_empty())\n        .unwrap_or_else(|| Path::new(\".\"));\n    let basename = to\n        .file_name()\n        .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, \"invalid destination path\"))?;\n\n    let dir_fd = openat(\n        CWD,\n        parent,\n        OFlags::DIRECTORY | OFlags::RDONLY | OFlags::CLOEXEC | OFlags::NOFOLLOW,\n        Mode::empty(),\n    )?;\n\n    let mut urandom = fs::File::open(\"/dev/urandom\")?;\n\n    for _ in 0..32 {\n        let mut tmp_bytes = *b\"Cu------\";\n        let mut raw = [0u8; 6];\n        urandom.read_exact(&mut raw)?;\n        for (slot, byte) in tmp_bytes[2..].iter_mut().zip(raw) {\n            *slot = ALPHABET[(byte as usize) % ALPHABET.len()];\n        }\n        let tmp = OsStr::from_bytes(&tmp_bytes);","sourceCodeStart":1057,"sourceCodeEnd":1093,"githubUrl":"https://github.com/uutils/coreutils/blob/85295bbf788bfd7a6926ba692031563504b304b7/src/uu/mv/src/mv.rs#L1057-L1093","documentation":"In the symlink-replacement fallback, mv derives the destination's parent and basename via openat-based atomic replacement. If the destination path has no final component (e.g., it is '.' , '..' , '/' or ends in '..'), to.file_name() returns None and this InvalidInput error is raised. It protects the low-level create_symlink_replace logic from a destination it cannot split into dir + name.","triggerScenarios":"Calling mv with a symlink destination that is a bare directory reference like `mv -T link .`, `mv src ..`, `mv src /`, or a trailing path that normalizes to a directory with no filename.","commonSituations":"Scripts building destination paths from variables that end up empty or as '.'/'..'; typos with trailing slashes or dot components; using mv -T with directory-valued targets.","solutions":["Pass a real destination filename, not '.', '..' or the filesystem root","Normalize the destination with `realpath`/canonicalize in scripts before invoking mv","Validate the target in scripts: ensure it has a basename component (e.g., `[ -n \"$(basename \"$dest\")\" ]` and dest != . / .. )","If the intent was 'move into directory', drop -T/--no-target-directory and let mv resolve the dir"],"exampleFix":"// before\nmv -T newlink .\n// after\nmv -T newlink /path/to/existing-link-name","handlingStrategy":"validation","validationCode":"# ensure destination has a basename and is not '.' / '..' / '/'\ncase \"$dest\" in\n  \"\"|\".\"|\"..\"|\"/\"|\".\") echo \"invalid destination path\"; exit 1;;\nesac\ncase \"$dest\" in *[!/]*/) echo \"trailing slash on non-dir target\" ;; esac","typeGuard":null,"tryCatchPattern":"null","preventionTips":["Validate path variables with realpath/canonicalize before mv","Reject destinations without a filename component in scripts","Be careful combining -T with directory-valued targets"],"tags":["mv","symlink","path","invalid-input"],"backgroundTag":"invalid-destination-path","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"}