Skip to content

fix: [node-core-library] Retry transient Windows EPERM/EBUSY in FileSystem.deleteFolder(Async)#5836

Open
bartvandenende-wm wants to merge 2 commits into
microsoft:mainfrom
bartvandenende-wm:bartvandenende-wm/5373
Open

fix: [node-core-library] Retry transient Windows EPERM/EBUSY in FileSystem.deleteFolder(Async)#5836
bartvandenende-wm wants to merge 2 commits into
microsoft:mainfrom
bartvandenende-wm:bartvandenende-wm/5373

Conversation

@bartvandenende-wm

@bartvandenende-wm bartvandenende-wm commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Restores retry-on-transient-error behavior to FileSystem.deleteFolder and FileSystem.deleteFolderAsync on Windows, fixing EPERM: operation not permitted, rmdir failures during rush rebuild / Heft cleanFiles on self-hosted Windows runners.

Fixes #5373.

Details

Root cause
In v5.11.0 (PR #5088) node-core-library bumped its fs-extra dependency from ~7.0.1 to ~11.3.0.

  • The v7 implementation of fs-extra.remove(Sync) was backed by rimraf@2, which retries EBUSY/EPERM/ENOTEMPTY on Windows by default (maxBusyTries: 3).
  • From fs-extra@10 onward, remove(Sync) is a thin wrapper around fs.rm(path, { recursive: true, force: true }) with no retry options.

The retry behavior was silently lost, which made consumers susceptible to the documented Windows transient where another process briefly holds a handle to a child of the directory being removed.

Change
Replace the two affected methods with native fs.rmSync / fsPromises.rm using { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }. fs-extra@11's remove(Sync) is already a thin wrapper over the same native call.

Note
I also added ensureEmptyFolder / ensureEmptyFolderAsync for consistency as they exhibit the same regression.

How it was tested

manual testing

@bartvandenende-wm

Copy link
Copy Markdown
Contributor Author

@iclanton any chance this could get a review?

@DavidRieman

DavidRieman commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

(FWIW: Although we're at the same company, I did independently encounter and come up with basically the same solution as Bart did, just on a different repo. Without the fix, a very basic one-line TS "hello world" with just TS+heft as the main dependencies will hit the EPERM issue maybe about a quarter of the time, simply from heft build --clean on Windows.)

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

Labels

None yet

Projects

Status: Needs triage

Development

Successfully merging this pull request may close these issues.

[heft] Windows support regression

2 participants