Skip to content

fs: ignore deleted dirs in recursive watch scan#63686

Open
trivikr wants to merge 1 commit into
nodejs:mainfrom
trivikr:test-fs-watch-recursive-delete
Open

fs: ignore deleted dirs in recursive watch scan#63686
trivikr wants to merge 1 commit into
nodejs:mainfrom
trivikr:test-fs-watch-recursive-delete

Conversation

@trivikr
Copy link
Copy Markdown
Member

@trivikr trivikr commented Jun 1, 2026

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-bot nodejs-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 thread lib/internal/fs/recursive_watch.js
@trivikr trivikr 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
Copy link
Copy Markdown

codecov Bot commented Jun 1, 2026

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 4 commits behind head on main.

Files with missing lines Patch % Lines
lib/internal/fs/recursive_watch.js 0.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 lines Coverage Δ
lib/internal/fs/recursive_watch.js 85.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-actions github-actions Bot 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

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

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants