remix-run/react-router · error
The `future.v8_viteEnvironmentApi` flag has been removed bec
Error message
The `future.v8_viteEnvironmentApi` flag has been removed because Vite Environment API usage is now always enabled
What it means
This is a fatal config-validation error from @react-router/dev's readConfig: when react-router.config.ts contains a `future.unstable_viteEnvironmentApi` or `future.v8_viteEnvironmentApi` key, the dev server / build aborts. In this version the Vite Environment API is used unconditionally, so the flag no longer does anything and its presence means the config predates the current major version. The check uses `in` on the future object, so even `viteEnvironmentApi: false` triggers it.
Source
Thrown at packages/react-router-dev/config/config.ts:711
}
}
// Check for renamed flags and provide helpful error messages
let futureConfig = userAndPresetConfigs.future;
if (futureConfig) {
if (
"unstable_splitRouteModules" in futureConfig ||
"v8_splitRouteModules" in futureConfig
) {
return err(
"The `future.v8_splitRouteModules` flag has been moved to a top-level `config.splitRouteModules` field (default `true`)",
);
}
if (
"unstable_viteEnvironmentApi" in futureConfig ||
"v8_viteEnvironmentApi" in futureConfig
) {
return err(
"The `future.v8_viteEnvironmentApi` flag has been removed because Vite Environment API usage is now always enabled",
);
}
if (
"unstable_passThroughRequests" in futureConfig ||
"v8_passThroughRequests" in futureConfig
) {
return err(
"The `future.v8_passThroughRequests` flag has been removed because pass-through requests are now the default behavior",
);
}
if (
"unstable_middleware" in futureConfig ||
"v8_middleware" in futureConfig
) {
return err(
"The `future.v8_middleware` flag has been removed because middleware is now always enabled",
);View on GitHub (pinned to 6beaca3952)
Solutions
- Delete the `v8_viteEnvironmentApi` (or `unstable_viteEnvironmentApi`) key from the `future` object in react-router.config.ts — the behavior it enabled is always on now
- Grep the repo for `viteEnvironmentApi` to catch the flag in presets, extends configs, comments, and stale FutureConfig typings
- Re-run `npx react-router typegen` and `pnpm typecheck` so leftover references to the removed flag surface as type errors
- Skim the upgrade guide for the other removed v8_* flags (passThroughRequests, middleware, trailingSlashAwareDataRequests, splitRouteModules, subResourceIntegrity) and clean them all in one pass
Example fix
// before - react-router.config.ts
export default {
future: { v8_viteEnvironmentApi: true },
} satisfies Config;
// after
export default {} satisfies Config; // Vite Environment API is always enabled Defensive patterns
Strategy: validation
Validate before calling
// run before `react-router dev/build` — fail fast on removed flags
import fs from "node:fs";
let cfg = fs.readFileSync("react-router.config.ts", "utf8");
let banned = ["v8_viteEnvironmentApi", "unstable_viteEnvironmentApi"];
let hits = banned.filter((k) => cfg.includes(k));
if (hits.length) {
throw new Error(`Remove removed future flags from react-router.config.ts: ${hits.join(", ")}`);
} Type guard
// narrows a parsed config to the current (post-removal) FutureConfig shape
type CurrentFuture = { unstable_enableNodeReadableStream?: boolean; unstable_optimizeDeps?: boolean };
function isCurrentFutureConfig(f: unknown): f is CurrentFuture {
if (typeof f !== "object" || f === null) return false;
return !("v8_viteEnvironmentApi" in f || "unstable_viteEnvironmentApi" in f);
} Try / catch
try {
let result = await readConfig(rootDirectory);
if (result.ok) run(result.value);
} catch (e) {
if (e instanceof Error && e.message.includes("v8_viteEnvironmentApi")) {
// strip the key from react-router.config.ts and re-run once, then surface to the user
} else throw e;
} Prevention
- Treat major-version bumps of @react-router/dev as breaking: read the upgrade guide's removed-flags table before merging
- Run `npx react-router typegen && tsc --noEmit` in CI so removed flag keys fail the type check
- Keep react-router.config.ts minimal and avoid spreading shared future objects between apps of different versions
When it happens
Trigger: Running `react-router dev`, `react-router build`, typegen, or any code path that calls readConfig while `future` in react-router.config.ts (or a preset/extends config) contains the key `unstable_viteEnvironmentApi` or `v8_viteEnvironmentApi`, with any value including false/null.
Common situations: Upgrading a v7 app that opted into the Vite Environment API early; copying an old config from a tutorial or another repo; CI suddenly failing right after bumping @react-router/dev to the next major.
Related errors
- The `future.v8_passThroughRequests` flag has been removed be
- The `future.v8_middleware` flag has been removed because mid
- The `future.v8_trailingSlashAwareDataRequests` flag has been
- The `future.unstable_subResourceIntegrity` flag has been sta
- React Router Vite plugin not found in Vite config
AI-assisted analysis of remix-run/react-router@6beaca3952 (2026-08-18).
Data as JSON: /api/errors/eec3f7b2e5e024b4.
Report an issue: GitHub.