Skip to content

fs: ignore deleted dirs in recursive watch scan - #63686

Merged
nodejs-github-bot merged 1 commit into
nodejs:mainfrom
trivikr:test-fs-watch-recursive-delete
Jun 3, 2026
Merged

fs: ignore deleted dirs in recursive watch scan#63686
nodejs-github-bot merged 1 commit into
nodejs:mainfrom
trivikr:test-fs-watch-recursive-delete

Conversation

@trivikr

Copy link
Copy Markdown
Member

Fixes a race in the non-native recursive fs.watch() implementation.

When a directory is removed recursively, the watcher can observe the child
directory from the parent watcher and then attempt to scan it after it has
already been deleted. In that case, readdirSync() throws ENOENT, which was
emitted as a watcher error and could crash tests with an unhandled error
event.

This treats ENOENT during the recursive directory scan as a normal deletion
race, while preserving existing error reporting for other failures.

Refs: https://github.com/nodejs/reliability/blob/main/reports/2026-06-01.md#jstest-failure

Example Error log
not ok 1330 parallel/test-fs-watch-recursive-delete --- duration_ms: 826.25800 severity: fail exitcode: 1 stack: |- node:events:487 throw er; // Unhandled 'error' event ^ Error: ENOENT: no such file or directory, scandir '/home/iojs/node-tmp/.tmp.1329/parent/child' at readdirSync (node:fs:1554:26) at #watchFolder (node:internal/fs/recursive_watch:122:21) at FSWatcher.<anonymous> (node:internal/fs/recursive_watch:208:26) at FSWatcher.emit (node:events:509:20) at FSWatcher._handle.onchange (node:internal/fs/watchers:279:12) Emitted 'error' event on FSWatcher instance at: at #watchFolder (node:internal/fs/recursive_watch:160:12) at FSWatcher.<anonymous> (node:internal/fs/recursive_watch:208:26) at FSWatcher.emit (node:events:509:20) at FSWatcher._handle.onchange (node:internal/fs/watchers:279:12) { errno: -2, code: 'ENOENT', syscall: 'scandir', path: '/home/iojs/node-tmp/.tmp.1329/parent/child' } Node.js v27.0.0-pre ...

Assisted-by: openai:gpt-5.5

A recursively watched directory can be removed after a parent watcher
observes it but before the non-native recursive watcher scans it.
Ignore ENOENT from the directory scan so this deletion race does not
emit an unhandled watcher error.
Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: openai:gpt-5.5
@nodejs-github-botnodejs-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 1, 2026
Comment threadlib/internal/fs/recursive_watch.js
@trivikrtrivikr added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. labels Jun 1, 2026
@codecov

codecovBot commented Jun 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.35%. Comparing base (9e58d9d) to head (a80cd49).
⚠️ Report is 29 commits behind head on main.

Files with missing linesPatch %Lines
lib/internal/fs/recursive_watch.js0.00%3 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #63686 +/- ##
=======================================
Coverage 90.34% 90.35% =======================================
Files 732 732 Lines 236507 236529 +22 Branches 44531 44534 +3 =======================================
+ Hits 213684 213704 +20 - Misses 14525 14540 +15 + Partials 8298 8285 -13 
Files with missing linesCoverage Δ
lib/internal/fs/recursive_watch.js85.37% <0.00%> (+0.10%)⬆️

... and 33 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actionsgithub-actionsBot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jun 1, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@trivikrtrivikr added the commit-queue Add this label to land a pull request using GitHub Actions. label Jun 3, 2026
@nodejs-github-botnodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Jun 3, 2026
@nodejs-github-bot
nodejs-github-bot merged commit 4d7996f into nodejs:mainJun 3, 2026
86 checks passed
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Landed in 4d7996f

@trivikr
trivikr deleted the test-fs-watch-recursive-delete branch June 4, 2026 05:02
@trivikr
trivikr restored the test-fs-watch-recursive-delete branch June 4, 2026 05:03
aduh95 pushed a commit that referenced this pull request Jun 18, 2026
A recursively watched directory can be removed after a parent watcher
observes it but before the non-native recursive watcher scans it.
Ignore ENOENT from the directory scan so this deletion race does not
emit an unhandled watcher error.
Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: openai:gpt-5.5
PR-URL: #63686
Refs: https://github.com/nodejs/reliability/blob/main/reports/2026-06-01.md#jstest-failure
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
aduh95 pushed a commit that referenced this pull request Jun 25, 2026
A recursively watched directory can be removed after a parent watcher
observes it but before the non-native recursive watcher scans it.
Ignore ENOENT from the directory scan so this deletion race does not
emit an unhandled watcher error.
Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: openai:gpt-5.5
PR-URL: #63686
Refs: https://github.com/nodejs/reliability/blob/main/reports/2026-06-01.md#jstest-failure
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
aduh95 pushed a commit that referenced this pull request Jul 30, 2026
A recursively watched directory can be removed after a parent watcher
observes it but before the non-native recursive watcher scans it.
Ignore ENOENT from the directory scan so this deletion race does not
emit an unhandled watcher error.
Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: openai:gpt-5.5
PR-URL: #63686
Refs: https://github.com/nodejs/reliability/blob/main/reports/2026-06-01.md#jstest-failure
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author readyPRs that have at least one approval, no pending requests for changes, and a CI started.fsIssues and PRs related to the fs subsystem / file system.needs-ciPRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@trivikr@nodejs-github-bot@lpinca@MoLow