remix-run/react-router · error

React Router config loading requires Vite's __config_loader…

Error message

React Router config loading requires Vite's __config_loader environment to be runnable.

What it means

When React Router loads react-router.config.ts, it boots an inline Vite dev server with a dedicated environment named '__config_loader', created through vite.createRunnableDevEnvironment. After creating the server it asserts vite.isRunnableDevEnvironment(environment); if that returns false — typically because user vite config or a plugin overrode environments.__config_loader.createEnvironment with a non-runnable environment, or the resolved Vite version's environment API doesn't match — config loading cannot execute and the error is thrown after closing the dev server.

Solutions

  1. Scope custom environments config to 'client' and 'ssr' only and remove any '__config_loader' key
  2. Align the vite version with the peer range @react-router/dev requires (dedupe vite in the lockfile)
  3. If a plugin injects environment factories, restrict it so it skips the __config_loader environment

Example fix

// before (vite.config.ts)
export default defineConfig({
  environments: {
    __config_loader: { createEnvironment: myCustomEnv }, // clobbers React Router's
  },
});

// after
export default defineConfig({
  environments: {
    client: { /* ... */ },
    ssr: { /* ... */ }, // leave __config_loader to React Router
  },
});
Defensive patterns

Strategy: validation

Validate before calling

import { resolveConfig } from "vite";
const cfg = await resolveConfig({ configFile: "vite.config.ts" }, "serve");
if (cfg.environments && "__config_loader" in cfg.environments) {
  throw new Error("Remove custom __config_loader environment config — React Router owns it");
}

Prevention

When it happens

Trigger: A vite.config.ts that defines environments.__config_loader (or a plugin hook that injects environment config matching every environment) with a custom non-runnable createEnvironment; a mismatched/duplicated Vite version resolved in the workspace.

Common situations: Adding per-environment config for client/ssr and accidentally covering __config_loader; monorepo/pnpm hoisting pulling a different vite instance than the one @react-router/dev expects; upgrading Vite major versions ahead of React Router support.

Related errors


AI-assisted analysis of remix-run/react-router@6beaca3952 (2026-08-18). Data as JSON: /api/errors/288d0edf90795db0. Report an issue: GitHub.

Appendix: source

Thrown at packages/react-router-dev/vite/vite-runner.ts:66

    configFile: false,
    envDir: false,
    plugins: [],
    environments: {
      __config_loader: {
        consumer: "server",
        dev: {
          createEnvironment: (name, config, context) =>
            vite.createRunnableDevEnvironment(name, config),
        },
      },
    },
  });

  const environment = devServer.environments.__config_loader;

  if (!vite.isRunnableDevEnvironment(environment)) {
    await devServer.close();
    throw new Error(
      "React Router config loading requires Vite's __config_loader environment to be runnable.",
    );
  }

  return { devServer, environment, runner: environment.runner };
}

View on GitHub (pinned to 6beaca3952)