uutils/coreutils · error · io::Error

mv-error-dangling-symlink

Error message

mv-error-dangling-symlink

What it means

`rename_symlink_fallback` re-creates a symlink at the destination and deletes the source link; if the original symlink is dangling (its target does not exist), the fallback cannot determine/recreate the target and raises this NotFound-kind error instead of moving a link pointing nowhere.

Solutions

  1. Recreate the symlink target before moving (`ln -s <correct-target> <link>` then mv)
  2. Delete the dangling link if it is no longer needed (`rm <link>`)
  3. Use `cp -a` / `tar` to copy the tree, which preserves dangling links, then remove the source
  4. Fix the link targets (e.g. relative instead of absolute paths) before the move

Example fix

// before
mv tree/ /otherfs/    # tree/link -> /mnt/old/target (missing)
// after
ln -s /new/target tree/link && mv tree/ /otherfs/
Defensive patterns

Strategy: validation

Validate before calling

# detect dangling links that mv will refuse to relocate across filesystems
find tree -xtype l -print   # lists broken symlinks

Type guard

fn is_dangling_link(p: &Path) -> bool {
    p.is_symlink() && !p.exists()
}

Try / catch

match mv_result {
    Err(e) if e.to_string().contains("dangling symlink") => {
        eprintln!("fix or delete broken links in the source tree, then retry");
    }
    r => r?,
}

Prevention

When it happens

Trigger: `mv` with a dangling symlink as source (or a cross-filesystem rename falling back to symlink recreation) where `path_symlink_points_to` fails to resolve/stat.

Common situations: Moving directory trees that contain broken symlinks (deleted targets, mounts not yet present, typos in link targets), especially between filesystems where rename falls back.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of uutils/coreutils@92995feca2 (2026-09-20). Data as JSON: /api/errors/f5b467aa98daa2e9. Report an issue: GitHub.

Appendix: source

Thrown at src/uu/mv/src/mv.rs:1077

    ))]
    {
        let _ = fsxattr::copy_xattrs_ignore_unsupported(from, to);
    }
    let _ = preserve_ownership(from, to);
    fs::remove_file(from)
}
#[cfg(windows)]
fn rename_symlink_fallback(from: &Path, to: &Path) -> io::Result<()> {
    let path_symlink_points_to = fs::read_link(from)?;
    if path_symlink_points_to.exists() {
        if path_symlink_points_to.is_dir() {
            windows::fs::symlink_dir(&path_symlink_points_to, to)?;
        } else {
            windows::fs::symlink_file(&path_symlink_points_to, to)?;
        }
        fs::remove_file(from)
    } else {
        Err(io::Error::new(
            io::ErrorKind::NotFound,
            translate!("mv-error-dangling-symlink"),
        ))
    }
}

#[cfg(target_os = "wasi")]
fn rename_symlink_fallback(_from: &Path, _to: &Path) -> io::Result<()> {
    Err(io::Error::other(translate!("mv-error-no-symlink-support")))
}

fn rename_dir_fallback(
    from: &Path,
    to: &Path,
    display_manager: Option<&MultiProgress>,
    verbose: bool,
    #[cfg(unix)] hardlink_tracker: Option<&mut HardlinkTracker>,
    #[cfg(unix)] hardlink_scanner: Option<&HardlinkGroupScanner>,

View on GitHub (pinned to 92995feca2)