Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bundledDev: undelivered HMR state has no recovery path

Two separate failures, one repro app. Vite 8.2.0, experimental.bundledDev: true.

The plugin in vite.config.ts drops the first WS message of one type sent to a client, standing in for a message lost in transit.

Issue 1 — a dropped reload request silences HMR permanently

pnpm install
pnpm dev:reload
  1. Open the page. It shows VERSION-1.
  2. Edit no-boundary.js (change the string). Nothing accepts this module, so the client asks the server for a full reload. The plugin drops the server's reply.
  3. Edit dep.js, changing VERSION-1 to VERSION-2.

Expected: step 3 either applies over HMR or reloads the page.

Actual: nothing happens, and nothing happens for any later edit either. No console error, no overlay. Only a manual refresh recovers.

requestFullReload sets reloadPending = true before it knows the server will honor the request (bundledDevHmrClient.ts:301-302), and nothing ever clears it. Both applyPush (line 176) and requestFullReload (line 301) early-return on it, so one lost message is terminal.

The loss is reachable without a plugin: the server's handler returns without replying when this.clients.getId(client) misses (bundledDev.ts:155-156). Registration happens on vite:client-connected (line 130), so a client that asks during a server restart can miss.

Issue 2 — a lost patch with no follow-up is never detected

pnpm install
pnpm dev:patch
  1. Open the page. It shows VERSION-1.
  2. Edit dep.js, changing VERSION-1 to VERSION-2. The plugin drops that one patch.
  3. Stop. Make no further edits.

Expected: the client or server notices the patch never arrived and recovers.

Actual: the page shows VERSION-1 forever. No error, no reload.

The sequence check lives inside applyPush (bundledDevHmrClient.ts:177), so it can only fire when a later patch arrives. Editing dep.js again does recover, which hides this in normal use — a human makes another edit within seconds.

It does not self-heal for an AI coding agent. A turn writes several new files that generate no patch, then one file that imports them all, which produces the only patch of the turn. Lose that and the preview is stale until the user refreshes, with nothing indicating why.

The server already knows: pendingPayloadFilenames holds every patch that was sent but never served, and markPayloadDelivered clears it when the request completes (bundledDev.ts:333, 344). Today that state only feeds the ship map so later chunks can re-include the missed modules. Nothing reloads a client that will never get a later chunk.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages