remix-run/react-router · error

Error loading ${reactRouterConfigFile}: ${error}

Error message

Error loading ${reactRouterConfigFile}: ${error}

What it means

Any exception thrown while the Vite runner imports the React Router config file is wrapped in this message — the `${error}` suffix carries the underlying cause. Because the config file is loaded through Vite (supporting TS, imports of other modules, env usage), failures range from syntax errors to missing relative imports to exceptions in code the config executes at module scope.

Source

Thrown at packages/react-router-dev/config/config.ts:483

      if (configModule.default === undefined) {
        return err(`${reactRouterConfigFile} must provide a default export`);
      }

      if (typeof configModule.default !== "object") {
        return err(`${reactRouterConfigFile} must export a config`);
      }

      reactRouterUserConfig = configModule.default;

      if (validateConfig) {
        const error = validateConfig(reactRouterUserConfig);
        if (error) {
          return err(error);
        }
      }
    } catch (error) {
      return err(`Error loading ${reactRouterConfigFile}: ${error}`);
    }
  }

  // Prevent mutations to the user config
  reactRouterUserConfig = deepFreeze(cloneDeep(reactRouterUserConfig));

  let presets: ReactRouterConfig[] = (
    await Promise.all(
      (reactRouterUserConfig.presets ?? []).map(async (preset) => {
        if (!preset.name) {
          throw new Error(
            "React Router presets must have a `name` property defined.",
          );
        }

        if (!preset.reactRouterConfig) {
          return null;
        }

View on GitHub (pinned to 6beaca3952)

Solutions

  1. Read the tail of the message — it contains the real error (parse error with line/column, resolve error with the module name, or a runtime message).
  2. Fix the referenced syntax error or import path in the config file.
  3. If an env var access throws, default it (`process.env.X ?? fallback`) or add it to your environment/`.env` and CI secrets.
  4. Ensure any package imported by the config is installed where the config is loaded (add to devDependencies for build-time).

Example fix

// before: react-router.config.ts
import { options } from "./shared/options"; // module missing / path typo
export default { ssr: options.ssr };

// after
export default {
  ssr: (process.env.SSR ?? "true") === "true",
};
Defensive patterns

Strategy: try-catch

Validate before calling

// smoke-import the config the same way the toolchain does, before CI build steps
import("./react-router.config.ts")
  .then(() => console.log("config loads"))
  .catch((e) => {
    console.error("react-router.config.ts fails to load:", e);
    process.exit(1);
  });

Try / catch

try {
  const config = await loadReactRouterConfig();
} catch (e) {
  // the wrapped message embeds the cause after ': '
  const cause = String(e).split(": ").slice(1).join(": ");
  console.error("Config load failed:", cause);
  process.exit(1);
}

Prevention

When it happens

Trigger: A syntax/parse error in `react-router.config.ts`; the config imports a module that fails to resolve (wrong relative path, missing dependency in node_modules); the config reads `process.env.SOME_VAR` and throws when it is undefined; a top-level await or side-effect that throws during import.

Common situations: Config imports a shared `./src/env.ts` whose path changed; using a package in the config that is a devDependency and missing in production/CI installs (`--production` install); accessing an env var that exists locally but not in CI; TS-only syntax errors after a toolchain upgrade.

Related errors


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