[vite 8.2.0] Fix REFLEX_ENV_MODE leak between AppHarness instances

Merged
MA
2mo ago
+126-11

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Description

Fixes a critical bug where AppHarnessProd leaked REFLEX_ENV_MODE=prod into subsequent dev AppHarness instances in the same process. When AppHarnessProd runs export(), it sets REFLEX_ENV_MODE=prod process-wide and never restores it. A dev AppHarness compiling later would then write prerender: true into its dev react-router config, causing the dev server to serve prerendered page HTML. On pages with hydration hazards, this failed hydration on every load and dropped events dispatched during the hydration-recovery window.

Root cause: The environment variable leak was masked by a vite 8.0.16 pin that was added to work around memo component re-rendering failures in the full integration suite. Those failures were actually caused by this REFLEX_ENV_MODE leak, not by vite itself.

Changes

  1. reflex/testing.py: Pin REFLEX_ENV_MODE to dev in AppHarness._initialize_app(), mirroring what reflex run does. This ensures dev harnesses always compile in dev mode regardless of prior AppHarnessProd instances.

  2. packages/reflex-base/src/reflex_base/constants/installer.py: Bump vite from 8.0.16 to 8.2.0 now that the root cause of the memo regression is fixed.

  3. Tests: Added test_app_harness_initialize_resets_leaked_prod_env_mode() to verify that dev AppHarness correctly resets REFLEX_ENV_MODE to dev mode and disables route prerendering, even when the environment variable was previously set to prod.

  4. News fragments: Added changelog entries documenting the bugfix and vite bump.

Update (2026-08-07): react-router 8.3.0 merge + docker-test fixes

Merged main (react-router 8.3.0 upgrade, #6854) into this branch so CI exercises the shipping combination, and fixed the two reflex-init-in-docker-test failures that upgrade introduced on main:

  1. packages/reflex-base/src/reflex_base/compiler/templates.py: Pin preview.host to 127.0.0.1 in the generated vite config. react-router 8 prerenders by fetching pages from a vite preview server started with the project's config; with no pinned host, the bound socket and the fetched http://localhost:<port>/ URL can resolve to different loopback address families (as in docker containers), failing reflex export with Prerender: Request failed for /: ECONNREFUSED. Same fix TanStack Router shipped for the identical failure (TanStack/router#6305). Full diagnosis in this comment.

  2. reflex/utils/exec.py: Pre-enable the development export condition (NODE_OPTIONS/BUN_OPTIONS) when starting the dev server. react-router 8's dev CLI otherwise re-executes itself to enable the condition, which bun does not honor on installs without node, tripping the CLI's restart guard and exiting the dev server. Details in this comment.

Test Plan

  • New regression test test_app_harness_initialize_resets_leaked_prod_env_mode() verifies the env-mode fix
  • New unit tests assert the generated vite config pins the preview host, and that the development condition is merged into NODE_OPTIONS/BUN_OPTIONS
  • Existing unit tests pass; memo playwright suites pass 10/10 on the merged react-router 8.3.0 + vite 8.2.0 tree
  • Node-free verification (reflex-managed bun 1.3.14, mirroring the docker image): fresh blank app reflex export succeeds, and reflex run --env dev serves 200 with zero restart errors

https://claude.ai/code/session_01AzeRM83L6J367wmwk9Gezk

&lt;img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"&gt;