nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
106.52k stars 29.03k forks source link

[fs.rm] Reports `ENOTEMPTY` randomly #54561

Open SukkaW opened 2 weeks ago

SukkaW commented 2 weeks ago

Version

v22.5.1

Platform

Darwin Sukka-Macbook-Pro.local 24.0.0 Darwin Kernel Version 24.0.0: Mon Aug 12 21:27:51 PDT 2024; root:xnu-11215.1.10~5/RELEASE_ARM64_T6020 arm64

Subsystem

No response

What steps will reproduce the bug?

I was building a rollup plugin that deletes the output folder/files:

import type { Plugin as RollupPlugin } from 'rollup';
import fsp from 'node:fs/promises';

export function cleandir(): RollupPlugin {
  return {
    name: 'cleandir',
    renderStart: {
      order: 'pre',
      async handler(outputOptions) {
        if (outputOptions.dir) {
          await fsp.rm(outputOptions.dir, { recursive: true, force: true });
          await fsp.mkdir(outputOptions.dir, { recursive: true });
        }
        if (outputOptions.file) {
          await fsp.rm(outputOptions.file, { recursive: true, force: true });
        }
      }
    }
  };
}

But I randomly encounter the following error:

src/index.ts → dist, dist...
[!] (plugin cleandir) Error: ENOTEMPTY: directory not empty, rmdir 'dist'
Error: ENOTEMPTY: directory not empty, rmdir 'dist'

ELIFECYCLE  Command failed with exit code 1.

How often does it reproduce? Is there a required condition?

About 1 in 8 times.

What is the expected behavior? Why is that the expected behavior?

fsp.rm should never reports ENOTEMPTY: directory not empty

What do you see instead?

Error: ENOTEMPTY: directory not empty, rmdir 'dist'

Additional information

I am running a parallel build inside a relatively large monorepo, which might have many file descriptors opened at once.

RedYetiDev commented 2 weeks ago

Hi! Can you make a reproduction without rollup as a dependency? Preferably, without any non-built in dependencies?

Secondly, can you try reproducing in v22.7.0? (Or v22.8.0 depending on when you see this message)

SukkaW commented 2 weeks ago

Hi! Can you make a reproduction without rollup as a dependency? Preferably, without any non-built in dependencies?

Since it happens randomly, I guess it might have something to do with many existing opened fs descriptors.

I am trying to extract a minimum reproduction.

RedYetiDev commented 2 weeks ago

I am trying to extract a minimum reproduction.

Great! Until that is done, it'll be hard to people to see what is going wrong.