Skip to content

fs: do not treat EPERM as ENOTEMPTY on Windows#5

Open
PickBas wants to merge 1 commit into
mainfrom
fs-rm-permissions-win
Open

fs: do not treat EPERM as ENOTEMPTY on Windows#5
PickBas wants to merge 1 commit into
mainfrom
fs-rm-permissions-win

Conversation

@PickBas
Copy link
Copy Markdown

@PickBas PickBas commented May 29, 2026

Changes

Refs nodejs#56433

fs.rm(..., { recursive: true }) on Windows treats EPERM from rmdir as "directory not empty" and recurses into children. That's wrong, because on Windows, EPERM means "no permission to delete", not "still has contents".

Windows now uses its own notEmptyErrorCodes set that excludes EPERM.

Safety

The EPERM treatment as non-empty traces to rimraf 2.2: (changelog, commit):

As per http://sourceforge.net/mailarchive/message.php?msg_id=31240176 sshfs-mounted directories return EPERM on rmdir called with non-empty dir. Hence removing non-empty directories mounted through sshfs didn't work with rimraf, and this change makes it work.

This does not apply to Windows, so EPERM is safely removed from notEmptyErrorCodes and is kept for other platforms.

Before/After

JS Script used as rm.js:

import { rmSync } from "fs";
import { rm } from "fs/promises";
const parentPath = "C:\\Users\\dev\\permissions\\folders";

await rm(parentPath, {recursive: true});

Before

PS C:\Users\dev\permissions> node.exe --max-old-space-size=30 .\rm.js

<--- Last few GCs --->
.6[25312:000001C3A99BC000]      515 ms: Mark-Compact 24.7 (87.4) -> 23.3 (89.4) MB, pooled: 0 MB, 2.46 / 0.00 ms  (+ 1.4 ms in 71 steps since start of marking, biggest step 0.1 ms, walltime since start of marking 9 ms) (average mu = 0.736, current mu = 0.70[25312:000001C3A99BC000]      592 ms: Mark-Compact 38.7 (89.4) -> 30.8 (96.4) MB, pooled: 0 MB, 10.28 / 0.00 ms  (+ 0.8 ms in 66 steps since start of marking, biggest step 0.2 ms, walltime since start of marking 20 ms) (average mu = 0.833, current mu = 0.
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory

After

PS C:\Users\dev\permissions> ..\node_projects\node\Release\node.exe --max-old-space-size=30 .\rm.js
node:internal/modules/run_main:107
    triggerUncaughtException(
    ^

[Error: EPERM: operation not permitted, rmdir 'C:\Users\kirill\dev\permissions\folders\00'] {
  errno: -4048,
  code: 'EPERM',
  syscall: 'rmdir',
  path: 'C:\\Users\\dev\\permissions\\folders\\00'
}

Node.js v27.0.0-pre

@PickBas PickBas requested a review from StefanStojanovic May 29, 2026 13:58
@PickBas PickBas changed the title Fs rm permissions win fs: don't treat EPERM as ENOTEMPTY on Windows May 29, 2026
@PickBas PickBas changed the title fs: don't treat EPERM as ENOTEMPTY on Windows fs: do not treat EPERM as ENOTEMPTY on Windows May 29, 2026
Signed-off-by: PickBas <sayed.kirill@gmail.com>
@PickBas PickBas force-pushed the fs-rm-permissions-win branch from 434f776 to 2e9d4da Compare May 29, 2026 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant