vitejs/vite · error · Error

Unsupported configLoader

Error message

Unsupported configLoader: ${configLoader}. Accepted values are 'bundle', 'runner', and 'native'.

What it means

loadConfigFromFile accepts a configLoader argument with exactly three valid values: 'bundle' (esbuild-bundle the config), 'runner' (module runner), and 'native' (native dynamic import). Any other value - including typos and legacy values - throws immediately before any file is loaded.

Solutions

  1. Use one of the three accepted values: 'bundle', 'runner', or 'native'.
  2. If you did not intend to set it, omit configLoader entirely (defaults to 'bundle').
  3. Check for typos when the value comes from an env var or CLI flag.

Example fix

// before
const cfg = await loadConfigFromFile(env, file, root, log, 'bundler')
// after
const cfg = await loadConfigFromFile(env, file, root, log, 'bundle')
Defensive patterns

Strategy: type-guard

Validate before calling

const VALID = new Set(['bundle', 'runner', 'native']);
function validateConfigLoader(loader) {
  return VALID.has(loader) ? null : `Unsupported configLoader: ${loader}`;
}

Type guard

function isConfigLoader(value) {
  return value === 'bundle' || value === 'runner' || value === 'native';
}

Prevention

When it happens

Trigger: Passing configLoader through the JS API or CLI (vite --configLoader=...) with an invalid string. Common after upgrading when a previously valid loader was renamed or removed.

Common situations: Upgrading Vite across versions where loader names changed; passing undefined explicitly; CLI scripts that template the loader name from CI variables.

Related errors


AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11). Data as JSON: /api/errors/f8a122a985336c46. Report an issue: GitHub.

Appendix: source

Thrown at packages/vite/src/node/config.ts:2381

export async function loadConfigFromFile(
  configEnv: ConfigEnv,
  configFile?: string,
  configRoot: string = process.cwd(),
  logLevel?: LogLevel,
  customLogger?: Logger,
  configLoader: 'bundle' | 'runner' | 'native' = 'bundle',
): Promise<{
  path: string
  config: UserConfig
  dependencies: string[]
} | null> {
  if (
    configLoader !== 'bundle' &&
    configLoader !== 'runner' &&
    configLoader !== 'native'
  ) {
    throw new Error(
      `Unsupported configLoader: ${configLoader}. Accepted values are 'bundle', 'runner', and 'native'.`,
    )
  }

  const start = performance.now()
  const getTime = () => `${(performance.now() - start).toFixed(2)}ms`

  let resolvedPath: string | undefined

  if (configFile) {
    // explicit config path is always resolved from cwd
    resolvedPath = path.resolve(configFile)
  } else {
    // implicit config file loaded from inline root (if present)
    // otherwise from cwd
    for (const filename of DEFAULT_CONFIG_FILES) {
      const filePath = path.resolve(configRoot, filename)
      if (!fs.existsSync(filePath)) continue

View on GitHub (pinned to b4d66fee14)