Skip to content

fix: report a file removed after startTime to a watcher attached later - #345

Merged
alexander-akait merged 2 commits into
mainfrom
fix/report-removal-after-start-time
Oct 13, 2026
Merged

alexander-akait merged 2 commits into
mainfrom
fix/report-removal-after-start-time

Conversation

@alexander-akait

@alexander-akait alexander-akait commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

Summary

A watcher attached with a startTime is told about files changed since then ("watch (outdated on attach)"), but not about files removed since then. webpack pauses its watcher during a build and attaches a new one with the build's start time afterwards, so a dependency deleted while a build runs never triggers a rebuild. This made restored-commonjs-reexport flaky on macOS in webpack/webpack#22640, where FSEvents can deliver deletions after another change has started a build.

DirectoryWatcher now records when a known file is removed, forgets it when the file reappears, and reports initial-missing on attach when the removal came after startTime. Paths watched as missing still ignore it, as before.

remove a.js after startTime, then attach a watcher with that startTime
before: no event
after:  aggregated: removals = [a.js]

What kind of change does this PR introduce?

fix

Did you add tests for your changes?

Yes, in test/Watchpack.test.js: "should detect a past removal of a file (watched)" (times out without the fix) and "should not detect a removal before the start time (watched)". Both share one options object so they share one watcher pool, as webpack does.

Does this PR introduce a breaking change?

No.

If relevant, what needs to be documented once your changes are merged or what have you already documented?

n/a

Use of AI

Claude Code traced the lost removal from webpack into DirectoryWatcher.watch, wrote the fix and the tests, and ran the suite and lint. A maintainer asked for the fix to land here rather than as a webpack workaround.

🤖 Generated with Claude Code

https://claude.ai/code/session_016ZdAw4de2GgWu4X7BMY8ys


Generated by Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Watchers attached after a file has been removed now report that removal when it occurred at or after their start time, including when the watcher is shared across instances.
    • Removals that occurred before a watcher’s start time are not reported as aggregated removal events. This preserves the distinction between changes relevant to a watcher’s timeframe and earlier removals.

@changeset-bot

changeset-bot Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cc817ae

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
watchpack Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 29274d5b-514e-4330-bf95-16be9db37dcb
📥 Commits

Reviewing files that changed from the base of the PR and between 93acee1 and cc817ae.

📒 Files selected for processing (2)
  • lib/DirectoryWatcher.js
  • test/Watchpack.test.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/Watchpack.test.js
  • lib/DirectoryWatcher.js

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.

Walkthrough

DirectoryWatcher now records timestamps for non-initial file removals and clears them when a path is observed again. When a watcher attaches and its target is missing, the check also compares the watcher’s start time with the recorded removal time. Added tests cover start times before and at the removal time.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to cc817

The reviewed removal-reporting behavior is consistent with the intended start-time handling and is ready to merge after normal checks.

Pre-merge checks · Passed 5
Passed Passed checks (5 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: reporting file removals after startTime to watchers attached later.
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 3…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

test/Watchpack.test.js

Oops! Something went wrong! :(

ESLint: 9.39.5

Error: Error while loading rule 'jest/no-deprecated-functions': Unable to detect Jest version - please ensure jest package is installed, or otherwise set version explicitly
Occurred while linting /test/Watchpack.test.js
at detectJestVersion (/.eslint-tmp/node_modules/eslint-plugin-jest/lib/rules/utils/detectJestVersion.js:22:9)
at create (/.eslint-tmp/node_modules/eslint-plugin-jest/lib/rules/no-deprecated-functions.js:31:107)
at Object.create (/.eslint-tmp/node_modules/@typescript-eslint/utils/dist/eslint-utils/RuleCreator.js:39:20)
at createRuleListeners (/.eslint-tmp/node_modules/eslint/lib/linter/linter.js:1019:15)
at /.eslint-tmp/node_modules/eslint/lib/linter/linter.js:1151:7
at Array.forEach ()
at runRules (/.eslint-tmp/node_modules/eslint/lib/linter/linter.js:1085:31)
at #flatVerifyWithoutProcessors (/.eslint-tmp/node_modules/eslint/lib/linter/linter.js:2115:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/.eslint-tmp/node_modules/eslint/lib/linter/linter.js:2203:43)
at Linter._verifyWithFlatConfigArray (/.eslint-tmp/node_modules/eslint/lib/linter/linter.js:2306:15)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 21757378-395d-45d3-b716-1f6b2a14309a
📥 Commits

Reviewing files that changed from the base of the PR and between 38505ef and 93acee1.

📒 Files selected for processing (4)
  • .changeset/report-removal-after-start-time.md
  • lib/DirectoryWatcher.js
  • test/Watchpack.test.js
  • types/DirectoryWatcher.d.ts

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.

Comment thread lib/DirectoryWatcher.js Outdated
Comment thread test/Watchpack.test.js Outdated
alexander-akait added a commit to webpack/webpack that referenced this pull request Oct 12, 2026
Regression test for the watchpack fix (webpack/watchpack#345); it passes
once watchpack is bumped to the release carrying it.
@codspeed

codspeed Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

⚠️ 4 benchmarks spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

✅ 36 untouched benchmarks


Comparing fix/report-removal-after-start-time (cc817ae) with main (38505ef)

Open in CodSpeed

@codecov

codecov Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.37%. Comparing base (38505ef) to head (cc817ae).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #345      +/-   ##
==========================================
+ Coverage   92.19%   92.37%   +0.18%     
==========================================
  Files           8        8              
  Lines        1307     1312       +5     
  Branches      385      388       +3     
==========================================
+ Hits         1205     1212       +7     
+ Misses         96       94       -2     
  Partials        6        6              
Flag Coverage Δ
integration 92.37% <100.00%> (+0.18%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 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.

@alexander-akait
alexander-akait merged commit d2143ec into main Oct 13, 2026
51 checks passed
@alexander-akait
alexander-akait deleted the fix/report-removal-after-start-time branch October 13, 2026 09:44
alexander-akait added a commit to webpack/webpack that referenced this pull request Oct 14, 2026
Regression test for the watchpack fix (webpack/watchpack#345); it passes
once watchpack is bumped to the release carrying it.
alexander-akait added a commit to webpack/webpack that referenced this pull request Oct 14, 2026
…22650)

* docs(agents): fix a dependency's bug in the dependency, not with a workaround

* fix(watch): rebuild when a file is removed while a build is running

Regression test for the watchpack fix (webpack/watchpack#345); it passes
once watchpack is bumped to the release carrying it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant