Skip to content

fix(plugin): resolve crash on invalidate() in plugin mode - #2378

Merged
alexander-akait merged 3 commits into
mainfrom
fix-plugin-mode-invalidate
Sep 2, 2026
Merged

fix(plugin): resolve crash on invalidate() in plugin mode#2378
alexander-akait merged 3 commits into
mainfrom
fix-plugin-mode-invalidate

Conversation

@bjohansebas

@bjohansebas bjohansebas commented Jul 29, 2026

Copy link
Copy Markdown
Member

When used as a plugin the host (webpack-cli, webpack-dev-server, etc.) owns compiler.watch(), so invalidate() threw because the middleware has no watching of its own. Invalidate the host's watching instead (each child compiler's one for a MultiCompiler on webpack < 5.109) and warn when the compiler is not watching at all.

Summary

What kind of change does this PR introduce?

Did you add tests for your changes?

Does this PR introduce a breaking change?

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

Use of AI


Note

Low Risk
Targeted fix to public invalidate() behavior in plugin mode with tests; standalone path unchanged when middleware owns watching.

Overview
Fixes a crash when invalidate() is called while webpack-dev-middleware runs as a plugin (isPlugin = true), where the middleware no longer owns a watching instance.

invalidate() now uses the middleware’s own watching when present (standalone usage). In plugin mode it forwards invalidation to the host’s compiler.watching, or to each child compiler’s watching on MultiCompiler when top-level watching is missing (webpack < 5.109). If nothing is watching, it logs a warning instead of throwing—aligned with existing plugin-mode close() behavior.

Plugin-mode tests cover host-owned invalidation and the no-watch warning; a changeset records the patch.

Reviewed by Cursor Bugbot for commit c801900. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed plugin-mode invalidation so rebuilds correctly trigger through the host compiler.
    • Improved invalidation for multi-compiler setups, including configurations where individual child compilers are watched.
    • Prevented crashes when no compilation is being watched; a warning is now shown and the callback completes safely.
    • Ensured callbacks run after the relevant host or child compiler rebuild completes.

@changeset-bot

changeset-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9cd68cc

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

This PR includes changesets to release 1 package
Name Type
webpack-dev-middleware 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

@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.23%. Comparing base (09a9095) to head (9cd68cc).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2378      +/-   ##
==========================================
+ Coverage   96.14%   96.23%   +0.09%     
==========================================
  Files          12       12              
  Lines        1660     1675      +15     
==========================================
+ Hits         1596     1612      +16     
+ Misses         64       63       -1     

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

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c801900. Configure here.

Comment thread src/index.js
bjohansebas and others added 2 commits September 2, 2026 16:15
When used as a plugin the host (webpack-cli, webpack-dev-server, etc.)
owns `compiler.watch()`, so `invalidate()` threw because the middleware
has no `watching` of its own. Invalidate the host's `watching` instead
(each child compiler's one for a `MultiCompiler` on webpack < 5.109)
and warn when the compiler is not watching at all.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The fix has three branches and the PR tested two: the host's own watching
and the warning when nothing is watching. Added coverage for the rest.

A MultiCompiler with its own watching now asserts each child is
invalidated exactly once -- MultiWatching already propagates, so this
fails if the fallback loop runs as well and invalidates them twice. The
fallback itself is driven by clearing the MultiCompiler's watching, which
is the shape webpack < 5.109 has, and asserts both children are reached.
Also covers the warning for a MultiCompiler watching nothing, and that the
callback still runs in plugin mode.
@alexander-akait
alexander-akait force-pushed the fix-plugin-mode-invalidate branch from c801900 to e2ed96e Compare September 2, 2026 16:38
@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: ad71ab26-6582-4a8a-9932-66ca049a39dd

📥 Commits

Reviewing files that changed from the base of the PR and between e2ed96e and 9cd68cc.

📒 Files selected for processing (3)
  • .changeset/plugin-mode-invalidate.md
  • src/index.js
  • test/pluginMode.test.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • .changeset/plugin-mode-invalidate.md
  • test/pluginMode.test.js
  • src/index.js

Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review.


Walkthrough

The invalidate() method now collects available host or child watching instances before registering callbacks. When no watching instance exists, it logs a warning and calls the callback with undefined stats. Tests cover single compilers, MultiCompiler instances, child watching fallbacks, rebuild callbacks, and non-watching hosts. A patch changeset documents the fix.

Merge Risk: ⚪ Minimal · up to 9cd68

This localized fix prevents invalidate() from crashing in plugin mode while preserving standalone behavior; no actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ 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: fixing the crash caused by calling invalidate() in plugin mode.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. (1 skipped: 1 …
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. (1 skipped: 1 unsupported.)

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-plugin-mode-invalidate

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.

ESLint install failed: dependency version conflict. Check your lock file or package.json.


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: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: a3d7ed57-edc8-425f-a380-db818c106f92

📥 Commits

Reviewing files that changed from the base of the PR and between 09a9095 and e2ed96e.

📒 Files selected for processing (4)
  • .changeset/plugin-mode-invalidate.md
  • src/index.js
  • test/__snapshots__/pluginMode.test.js.snap.webpack5
  • test/pluginMode.test.js

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.

Comment thread src/index.js Outdated
Reported by Cursor Bugbot. The no-op guard warned but left the callback
queued: ready() had already pushed it onto context.callbacks, and with
nothing to invalidate no build ever drains them, so invalidate(callback)
never returned. close() completes its callback on the same path.

The watchings to invalidate are now collected before anything runs, so
the no-op case is known before ready() is called and can complete the
callback directly. Ordering is otherwise unchanged -- ready() still runs
before invalidate(), which the 16 standalone invalidate tests cover.

The callback takes the build result rather than an error, so it gets no
stats here instead of close()'s null.
@alexander-akait
alexander-akait merged commit d816818 into main Sep 2, 2026
22 checks passed
@alexander-akait
alexander-akait deleted the fix-plugin-mode-invalidate branch September 2, 2026 17:28
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.

2 participants