nodejs / nodejs/node

Discrepancy between `fs.rmSync` and `fs/promises.rm` behavior with `.` and `..` in paths

Ouverte
#61,958 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

confirmed-bug fs
Langage dominant
JavaScript
Étoiles
122k
Forks
37.4k
Merge moyen
4 j 2 h
PR mergées (30 j)
283

Description

Version

v25.6.1

Platform
Darwin moxy.lan 25.3.0 Darwin Kernel Version 25.3.0: Wed Jan 28 20:47:03 PST 2026; root:xnu-12377.81.4~5/RELEASE_ARM64_T6031 arm64
Subsystem

lib/internal/fs/rimraf.js

What steps will reproduce the bug?

Create a nested folder:

mkdir -p a/b/c/d

Attempt to delete with this weirdly constructed path:

Welcome to Node.js v25.6.1.
Type ".help" for more information.
> await require('fs/promises').rm('a/b/../.', { recursive: true, force: true })
Uncaught [Error: EINVAL: invalid argument, rmdir 'a/b/../.'] {
  errno: -22,
  code: 'EINVAL',
  syscall: 'rmdir',
  path: 'a/b/../.'
}

Verify that nothing was removed:

$ tree
./
└── a/
    └── b/
        └── c/
            └── d/

Attempt to delete synchronously:

> require('fs').rmSync('a/b/../.', { recursive: true, force: true })
undefined

It was (mostly?) removed:

$ tree
./
└── a/

The weird thing is that a/b/../. should resolve to just a, so it's weird that it only deletes up to b. It's almost as if the rmSync method is coalescing /../. into just /.

Also, if the . is not the last item, then it seems to be fine? a/b/.././b deletes the b folder, and a/b/.. deletes just b, but not a.

At least, it seems like the sync and asynchronous methods should either both fail, or both succeed, with the same error.

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

every time, see repro steps above

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

sync and asynchronous rm methods should fail and succeed in the same way on the same input.

What do you see instead?

Some cases where rmSync succeeds, and fs/promises.rm fails.

Additional information

I have a fix that I could land in the upstream rimraf library, and I'd of course be happy to send a PR to node to bring it back into alignment, since there have also been some improvements in performance and Windows reliability.

But it'd be good to know what the intended behavior is, so that the errors can be made consistent with Node's intended design first.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par lib/internal/fs/rimraf.js et exécutez la reproduction signalée de a/b/../. pour fs/promises.rm et fs.rmSync. Comparez la manière dont chaque chemin est traité et déterminez le comportement cohérent attendu avant de vérifier les tests du système de fichiers environnants. C’est terminé lorsque les deux APIs ont le même comportement pour ces cas de chemins contenant des points et que la couverture de régression protège ce comportement.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
javascript, nodejs
Domaine
backend, operating-systems
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
Active
Clarté
Plutôt claire
Accessibilité débutants
55/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.