You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fs: rmSync() deletes a symlinked directory's contents then throws ENOTDIR when the path has a trailing slash #67186
rmSync() deletes everything inside the target directory, then throws ENOTDIR. The symlink and the directory itself survive.
rm() and fsPromises.rm() report success and delete nothing.
On v22.20.0, rmSync() throws ENOTDIR and deletes nothing, so the sync side regressed when rmSync moved to C++ in #53617 (7168295).
Additional information
Why the three behaviors differ:
rmSync() is std::filesystem::remove_all(). The trailing slash makes lstat() follow the link, so the path reports as a directory. remove_all opens the directory, unlinks each entry, then calls unlink("link/"), which fails with ENOTDIR. By then the entries are gone.
rm() and fsPromises.rm() use internal/fs/rimraf. lstat() also reports a directory, so _rmdir() calls rmdir("link/"), which fails with ENOTDIR. _rmdir() turns ENOTDIR into callback(originalErr), and originalErr is null on this path, so the call succeeds without touching anything.
POSIX rm -rf link/ deletes the directory contents, leaves the link and the directory, and exits 0. So the sync behavior matches the shell except for the error at the end.
#66673 normalizes dot segments but keeps a trailing slash, so it does not change this case.
I am happy to send a PR once there is agreement on which behavior is wanted: match rm -rf (delete contents, succeed), or treat the path as the symlink and refuse with ENOTDIR before deleting anything.
Activity