[PR #1027] [MERGED] fix(hmr): full-reload after a render error tears down BrowserRoot #1032

Closed
opened 2026-05-06 13:11:39 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/1027
Author: @james-elicx
Created: 5/2/2026
Status: Merged
Merged: 5/2/2026
Merged by: @james-elicx

Base: mainHead: fix/hmr-auto-reload-after-tear-down


📝 Commits (1)

  • 24a2a1e fix(hmr): full-reload after a render error tears down BrowserRoot

📊 Changes

1 file changed (+21 additions, -6 deletions)

View changed files

📝 packages/vinext/src/server/app-browser-entry.ts (+21 -6)

📄 Description

Summary

  • Stacked on top of #1026.
  • A render error (e.g. a server route throws) unmounts BrowserRoot, which clears setBrowserRouterState / browserRouterStateRef. After #1026 the rsc:update HMR handler bails silently in that state, leaving HMR effectively dead until a manual hard-refresh — the user's fix never lands automatically.
  • Track a sticky browserRouterStateHasEverCommitted flag (set in markBrowserRouterStateReady). When HMR fires and the tree was up before but isn't now, trigger window.location.reload() so the next push reconciles via a fresh load.

Loop safety

  • The reload only fires when hasEverCommitted && !ref — i.e. previously mounted, currently torn down. After the reload, if the broken code prevents BrowserRoot from mounting at all, hasEverCommitted is false on the new page load and subsequent HMR events fall through to the existing wait-for-readiness path. So no reload loop.

Test plan

  • On a working page, edit a server route to throw, save, observe RSC error tears down the page.
  • Fix the route, save — the page should auto-reload and recover instead of staying broken until manual refresh.
  • Normal HMR on a healthy page is unaffected (the new branch is gated on the sticky flag + null ref).

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/1027 **Author:** [@james-elicx](https://github.com/james-elicx) **Created:** 5/2/2026 **Status:** ✅ Merged **Merged:** 5/2/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `fix/hmr-auto-reload-after-tear-down` --- ### 📝 Commits (1) - [`24a2a1e`](https://github.com/cloudflare/vinext/commit/24a2a1e1607af886a1979e0b06a50584fcbafab5) fix(hmr): full-reload after a render error tears down BrowserRoot ### 📊 Changes **1 file changed** (+21 additions, -6 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/server/app-browser-entry.ts` (+21 -6) </details> ### 📄 Description ## Summary - Stacked on top of [#1026](https://github.com/cloudflare/vinext/pull/1026). - A render error (e.g. a server route throws) unmounts `BrowserRoot`, which clears `setBrowserRouterState` / `browserRouterStateRef`. After #1026 the `rsc:update` HMR handler bails silently in that state, leaving HMR effectively dead until a manual hard-refresh — the user's fix never lands automatically. - Track a sticky `browserRouterStateHasEverCommitted` flag (set in `markBrowserRouterStateReady`). When HMR fires and the tree was up before but isn't now, trigger `window.location.reload()` so the next push reconciles via a fresh load. ## Loop safety - The reload only fires when `hasEverCommitted && !ref` — i.e. previously mounted, currently torn down. After the reload, if the broken code prevents BrowserRoot from mounting at all, `hasEverCommitted` is `false` on the new page load and subsequent HMR events fall through to the existing wait-for-readiness path. So no reload loop. ## Test plan - [ ] On a working page, edit a server route to throw, save, observe RSC error tears down the page. - [ ] Fix the route, save — the page should auto-reload and recover instead of staying broken until manual refresh. - [ ] Normal HMR on a healthy page is unaffected (the new branch is gated on the sticky flag + null ref). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:11:39 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#1032
No description provided.