reflex-dev/reflex · warning
react-router hmr runtime changed; unloaded-route HMR patch s
Error message
react-router hmr runtime changed; unloaded-route HMR patch skipped
What it means
This is a JavaScript console warning emitted by a Vite plugin that Reflex injects into its generated vite.config.js. The plugin patches react-router's HMR runtime module (virtual:react-router/hmr-runtime) to replace the 'unloaded-route' throw with a no-op so HMR works with lazily loaded routes. When react-router changes its internal code shape, the regex (unloadedRouteThrow) no longer matches and the patch is skipped with this warning.
Source
Thrown at packages/reflex-base/src/reflex_base/compiler/templates.py:706
}});
return [];
}}
}};
}}
// React Router queues manifest updates for lazy routes even when their modules
// are not loaded. Its HMR runtime throws on those entries before clearing the
// queue, which blocks every later update until the browser is reloaded.
function patchReactRouterHmrRuntime() {{
const unloadedRouteThrow = /if\s*\(!imported\)\s*\{{\s*throw\s+Error\(\s*`\[react-router:hmr\] No module update found for route [^`]+`,\s*\);\s*\}}/;
return {{
name: "reflex-patch-react-router-hmr-runtime",
apply: "serve",
enforce: "post",
transform(code, id) {{
if (id !== "\0virtual:react-router/hmr-runtime") return;
if (!unloadedRouteThrow.test(code)) {{
this.warn(
"react-router hmr runtime changed; unloaded-route HMR patch skipped",
);
return;
}}
return {{
code: code.replace(unloadedRouteThrow, "if (!imported) continue;"),
map: null,
}};
}},
}};
}}
export default defineConfig((config) => ({{
base: "{base}",
plugins: [
alwaysUseReactDomServerNode(),
reactRouter(),
patchReactRouterHmrRuntime(),View on GitHub (pinned to 45b8ed5ab7)
Solutions
- Check your installed react-router/@react-router/dev version and align it with the version Reflex generates/pins in the output frontend package.json (remove manual overrides and re-run `reflex export --frontend` or delete .web and let it regenerate).
- Upgrade Reflex/reflex-base to the latest release, which may update the unloadedRouteThrow pattern for newer react-router.
- If HMR breaks (browser 'You cannot HMR an unloaded route' errors), restart `reflex dev` — full reload still works since only the HMR patch is skipped.
- Report the react-router version to the Reflex repo so the pattern in compiler/templates.py vite_config_template can be updated.
Example fix
// before (user package.json override in .web)
"overrides": { "react-router": "^7.2.0" }
// after: remove the override and use the version reflex generates
// delete .web / node_modules and re-run `reflex dev` Defensive patterns
Strategy: validation
Validate before calling
// in generated .web, before `npm run dev` type checks are not possible; instead check the installed version
// package.json of the exported frontend
"require('react-router/package.json').version" // verify it matches the version reflex pins; if not, reinstall deps Prevention
- Don't override react-router/@react-router/dev versions in .web/package.json; let Reflex generate them.
- Re-export the frontend (delete .web) after upgrading Reflex so plugin patterns and deps stay in sync.
- Pin Reflex and its generated frontend deps to compatible versions together.
When it happens
Trigger: Running `reflex dev` (Vite serve mode) after upgrading react-router (or @react-router/dev) to a version whose hmr-runtime module no longer contains the expected unloaded-route throw statement. The warning comes from the plugin's transform() hook when id === '\0virtual:react-router/hmr-runtime' but the pattern test fails.
Common situations: A reflex-base or Reflex framework bump pulls in a newer react-router version; or a user pins/overrides react-router in their project's package.json to an incompatible version. HMR of routes may then throw 'Unloaded route' errors in the browser on hot updates.
AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28).
Data as JSON: /api/errors/c79391919b557bf5.
Report an issue: GitHub.