Discrepancy between `fs.rmSync` and `fs/promises.rm` behavior with `.` and `..` in paths
Nessuno ha ancora preso questa issue.
- Lingua principale
- JavaScript
- Stelle
- 122k
- Fork
- 37.3k
- Merge medio
- 4g 2h
- PR unite (30g)
- 283
Descrizione
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.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia da lib/internal/fs/rimraf.js ed esegui la riproduzione segnalata di a/b/../. sia per fs/promises.rm sia per fs.rmSync. Confronta il modo in cui viene gestito ciascun percorso e determina il comportamento coerente previsto prima di controllare i test del filesystem circostanti. Il lavoro è completato quando le due API concordano per questi casi di percorsi con punti e la copertura di regressione protegge tale comportamento.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- javascript, nodejs
- Ambito
- backend, operating-systems
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Attiva
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 55/100