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('', { recursive: true }) deletes the contents of the current directory on Windows (Node throws ENOENT) #47420
Run this inside an empty scratch directory that holds one file. It deletes the contents of the current working directory, so do not run it anywhere else.
mkdir sandbox &&cd sandbox &&echo keep > sentinel.txt
bun -e "try { require('node:fs').rmSync('', { recursive: true }) } catch (e) { console.log(e.code) }"
ls -A
What is the expected behavior?
An empty path names no file, so nothing is removed and the call throws ENOENT. That is what Node v25.9.0 does for the same script: it throws ENOENT, and sentinel.txt is still there.
What do you see instead?
Bun removes everything inside the current working directory, then throws EBUSY: resource busy or locked, rm when it reaches the directory itself. sentinel.txt is gone.
The same happens for every recursive form we tried:
call
Bun 1.4.4
contents of cwd
fs.rmSync('')
throws ENOENT
kept (correct)
fs.rmSync('', { recursive: true })
throws EBUSY
deleted
fs.rmSync('', { recursive: true, force: true })
throws EBUSY
deleted
fs.promises.rm('', { recursive: true })
rejects EBUSY
deleted
fs.rmdirSync('', { recursive: true })
throws EBUSY
deleted
So the recursive path appears to resolve '' to the current directory, where the non-recursive path rejects it.
Additional information
We hit this in a real project. A test fixture's cleanup computed an empty path and called rmSync(path, { recursive: true }). The test was running with its cwd at the root of a git worktree, and it emptied the whole working tree, .git file included. Only Windows has been checked; we have not tried Linux or macOS.
Confirmed from the source: on Windows the recursive rm path resolves the empty name against the cwd handle, so NtCreateFile opens the cwd itself and deletes its contents.
Fix: #38052 (reports ENOENT for an empty name in that layer, rebased onto main and ready for review).
Activity
robobun commentedon Oct 30, 2026
Confirmed from the source: on Windows the recursive rm path resolves the empty name against the cwd handle, so
NtCreateFileopens the cwd itself and deletes its contents.Fix: #38052 (reports
ENOENTfor an empty name in that layer, rebased onto main and ready for review).