can1357/oh-my-pi · error · io::Error
can't determine symlink type, since it is dangling
Error message
can't determine symlink type, since it is dangling
What it means
Windows-only error from rename_symlink_fallback: when mv must re-create a symlink at the destination (inter-device/copy fallback instead of a plain rename), it needs to know whether the link points to a file or a directory to pick symlink_file vs symlink_dir. For a dangling symlink (its target does not exist), that cannot be determined, so the move fails with `can't determine symlink type, since it is dangling` (io::ErrorKind::NotFound). On Unix this case succeeds because symlink(2) copies the link contents verbatim.
Source
Thrown at crates/pi-builtins/src/mv.rs:1131
{
let _ = copy_xattrs_if_supported(host, from, to);
}
fs::remove_file(host.resolve(from))
}
#[cfg(windows)]
fn rename_symlink_fallback(host: &mut Host, from: &Path, to: &Path) -> io::Result<()> {
let path_symlink_points_to = fs::read_link(host.resolve(from))?;
let to_fs = host.resolve(to);
if path_symlink_points_to.exists() {
if path_symlink_points_to.is_dir() {
windows::fs::symlink_dir(&path_symlink_points_to, &to_fs)?;
} else {
windows::fs::symlink_file(&path_symlink_points_to, &to_fs)?;
}
fs::remove_file(host.resolve(from))
} else {
Err(io::Error::new(
io::ErrorKind::NotFound,
"can't determine symlink type, since it is dangling",
))
}
}
#[cfg(target_os = "wasi")]
fn rename_symlink_fallback(host: &mut Host, _from: &Path, _to: &Path) -> io::Result<()> {
Err(io::Error::other("your operating system does not support symlinks"))
}
fn rename_dir_fallback(
host: &mut Host,
from: &Path,
to: &Path,
display_manager: Option<&MultiProgress>,
verbose: bool,
#[cfg(unix)] hardlink_tracker: Option<&mut HardlinkTracker>,View on GitHub (pinned to 9690622007)
Solutions
- Restore or recreate the symlink's target so the link is not dangling before moving it
- Delete the dangling symlink and create a new one at the destination manually (New-Item -ItemType SymbolicLink)
- Move the operation to a Unix environment, where dangling symlinks are moved verbatim without error
- If you maintain the library, resolve the link type from the link's own metadata (reparse point flags) instead of probing the target
Example fix
// before (PowerShell) Move-Item C:\src\link.txt D:\dest\ # link.txt points to missing file // error: can't determine symlink type, since it is dangling // after New-Item -ItemType File -Path C:\src\target.txt | Out-Null # restore target Move-Item C:\src\link.txt D:\dest\
Defensive patterns
Strategy: validation
Validate before calling
const { lstatSync, readlinkSync, existsSync } = require("node:fs");
function isDanglingSymlink(p) {
const st = lstatSync(p, { throwIfNoEntry: false });
if (!st || !st.isSymbolicLink()) return false;
return !existsSync(p); // exists() follows links
}
// before a cross-drive move on Windows: if (isDanglingSymlink(link)) repairOrDeleteIt(link); Try / catch
try {
await run("mv", [src, dest]);
} catch (err) {
if (String(err.stderr).includes("dangling")) {
// recreate the link at destination manually, then remove source link
const target = readlinkSync(src);
await run("cmd", ["/c", "mklink", dest, target]);
await fs.promises.unlink(src);
} else throw err;
} Prevention
- Audit for dangling symlinks (targets missing) before cross-drive moves on Windows
- Repair or delete broken links as part of cleanup before moving directories
- On Unix, no guard is needed - dangling links move verbatim
- Keep symlink targets on the same volume as the links to avoid fallback moves
When it happens
Trigger: On Windows, moving a symlink whose target does not exist across a filesystem/device boundary (or any case where rename fails and rename_symlink_fallback runs): read_link succeeds, but path_symlink_points_to.exists() is false, so neither symlink_dir nor symlink_file can be chosen.
Common situations: Moving broken symlinks (targets deleted, moved, or on unmounted drives) between drives on Windows; test fixtures with dangling links; CI checkouts where symlink targets were not materialized.
Related errors
- Too many levels of symbolic links
- 2
- symlinks not supported on this platform
- cannot stat {0}: No such file or directory
- cannot stat {0}: Not a directory
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/2078d21140e28844.
Report an issue: GitHub.