Skip to content

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

Merged
nodejs-github-bot merged 1 commit into
nodejs:mainfrom
JaneaSystems:fs-rm-permissions-win
Jun 21, 2026
Merged

fs: do not treat EPERM as ENOTEMPTY on Windows#63709
nodejs-github-bot merged 1 commit into
nodejs:mainfrom
JaneaSystems:fs-rm-permissions-win

Conversation

@PickBas

@PickBas PickBas commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Changes

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

Fixes: #56433

@nodejs-github-bot nodejs-github-bot added fs Issues and PRs related to the fs subsystem / file system. needs-ci PRs that need a full CI run. labels Jun 2, 2026

@jazelly jazelly left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm! I believe we had this line since isaacs/rimraf@bd19df7

@jazelly jazelly added the request-ci Add this label to start a Jenkins CI on a PR. label Jun 9, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jun 9, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@StefanStojanovic StefanStojanovic added the commit-queue Add this label to land a pull request using GitHub Actions. label Jun 11, 2026
@jazelly jazelly added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. and removed needs-ci PRs that need a full CI run. labels Jun 11, 2026
@nodejs-github-bot nodejs-github-bot added commit-queue-failed An error occurred while landing this pull request using GitHub Actions. and removed commit-queue Add this label to land a pull request using GitHub Actions. labels Jun 11, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator
Commit Queue failed
- Loading data for nodejs/node/pull/63709
✔  Done loading data for nodejs/node/pull/63709
----------------------------------- PR info ------------------------------------
Title      fs: do not treat EPERM as ENOTEMPTY on Windows (#63709)
   ⚠  Could not retrieve the email or name of the PR author's from user's GitHub profile!
Branch     PickBas:fs-rm-permissions-win -> nodejs:main
Labels     fs, author ready
Commits    1
 - fs: do not treat EPERM as ENOTEMPTY on Windows
Committers 1
 - PickBas <sayed.kirill@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/63709
Fixes: https://github.com/nodejs/node/issues/56433
Reviewed-By: Jason Zhang <xzha4350@gmail.com>
Reviewed-By: Stefan Stojanovic <stefan.stojanovic@janeasystems.com>
------------------------------ Generated metadata ------------------------------
PR-URL: https://github.com/nodejs/node/pull/63709
Fixes: https://github.com/nodejs/node/issues/56433
Reviewed-By: Jason Zhang <xzha4350@gmail.com>
Reviewed-By: Stefan Stojanovic <stefan.stojanovic@janeasystems.com>
--------------------------------------------------------------------------------
   ℹ  This PR was created on Tue, 02 Jun 2026 11:30:51 GMT
   ✔  Approvals: 2
   ✔  - Jason Zhang (@jazelly): https://github.com/nodejs/node/pull/63709#pullrequestreview-4458260922
   ✔  - Stefan Stojanovic (@StefanStojanovic): https://github.com/nodejs/node/pull/63709#pullrequestreview-4476077951
   ✘  2 GitHub CI job(s) failed:
   ✘    - github-actions: ACTION_REQUIRED
   ✘    - github-actions: ACTION_REQUIRED
   ℹ  Last Full PR CI on 2026-06-09T12:48:58Z: https://ci.nodejs.org/job/node-test-pull-request/73999/
- Querying data for job/node-test-pull-request/73999/
✔  Build data downloaded
   ✔  Last Jenkins CI successful
--------------------------------------------------------------------------------
   ✔  Aborted `git node land` session in /home/runner/work/node/node/.ncu
https://github.com/nodejs/node/actions/runs/27344513498

@PickBas

PickBas commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

@StefanStojanovic @jazelly Please let me know if there's anything else I need to address to move this forward

@jazelly

jazelly commented Jun 20, 2026

Copy link
Copy Markdown
Member

looks like it failed because of the 2 remaining GHA. Can you amend the commit and force push to trigger the GHA again?

Fixes: nodejs#56433

Signed-off-by: PickBas <sayed.kirill@gmail.com>
@PickBas PickBas force-pushed the fs-rm-permissions-win branch from 66e9aaa to 557aa0e Compare June 20, 2026 15:31
@PickBas

PickBas commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

@jazelly Done, thank you! There are now 7 workflows awaiting approval. Please let me know if I should do anything else to move this forward

@jazelly jazelly added request-ci Add this label to start a Jenkins CI on a PR. and removed commit-queue-failed An error occurred while landing this pull request using GitHub Actions. labels Jun 20, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jun 20, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@jazelly jazelly added the commit-queue Add this label to land a pull request using GitHub Actions. label Jun 21, 2026
@nodejs-github-bot nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Jun 21, 2026
@nodejs-github-bot nodejs-github-bot merged commit 665daeb into nodejs:main Jun 21, 2026
68 checks passed
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Landed in 665daeb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. fs Issues and PRs related to the fs subsystem / file system.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fs.promises.rm recursive on a huge directory-tree with missing permissions can result in OOM

4 participants