vitest-dev/vitest · error · Error

The environment was not defined in the Vite config.

Error message

The environment ${environmentName} was not defined in the Vite config.

What it means

Thrown by the internal getEnvironment() helper inside the RPC pool worker when a fetch request names a Vite DevEnvironment that does not exist in project.vite.environments. The worker cannot transform or fetch modules for an environment it has no server for, so it aborts. This almost always points to a mismatch between the environment name a test/request uses and the environments actually declared in the Vite/Vitest config.

Solutions

  1. Verify the environment name in your vitest config 'environments' matches what the tests request (e.g. environments: { jsdom: {} }).
  2. Check that the environment plugin (e.g. @vitest/browser, jsdom environment) is installed and loaded without errors.
  3. Look at the server/Vite logs for environment registration failures that happened before this throw.
  4. If using a custom environment, confirm its name property and that defineEnvironment/resolveEnvironment registered it.
  5. On version upgrades, re-read the migration notes for the Vite environments API.

Example fix

// before
export default defineConfig({
  test: { environment: 'jsdom' }
})
// after - register the environment in vite environments
import { jsdom } from 'vitest/environments'
export default defineConfig({
  environments: { jsdom },
  test: { environment: 'jsdom' }
})
Defensive patterns

Strategy: validation

Validate before calling

// Before relying on an environment, confirm it was registered.
import type { Vite } from 'vite'
function assertEnvironment(vite: Vite, name: string) {
  if (!vite.environments?.[name]) {
  throw new Error(`Environment "${name}" is not registered. Available: ${Object.keys(vite.environments || {}).join(', ')}`)
  }
}
// assertEnvironment(project.vite, environmentName)

Type guard

const hasEnvironment = (vite: { environments?: Record<string, unknown> }, name: string): boolean =>
  Boolean(vite.environments && name in vite.environments)

Prevention

When it happens

Trigger: An RPC 'fetch' call is made with an environmentName that is not a key of project.vite.environments. Happens when a test project references an environment (e.g. 'jsdom', 'happy-dom', a custom environment) that was never registered, or when pool/workers were spawned from a config that differs from the one the server used.

Common situations: Declaring environments only under test environment options but not in vite.config environments, typos in the environment name, using a custom environment plugin that failed to load, mismatched config between the main process and forked workers, or upgrading Vite/Vitest where the environments API shape changed.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/1c308c447ea40bf8. Report an issue: GitHub.

Appendix: source

Thrown at packages/vitest/src/node/pools/rpc.ts:50

const warmExternals = new WeakMap<DevEnvironment, Record<string, FetchResult>>()

export function createMethodsRPC(project: TestProject, methodsOptions: MethodsOptions = {}): RuntimeRPC {
  const vitest = project.vitest
  const cacheFs = methodsOptions.cacheFs ?? false
  project.vitest.state.metadata[project.name] ??= {
    externalized: {},
    duration: {},
    tmps: {},
  }
  if (project.config.dumpDir && !existsSync(project.config.dumpDir)) {
    mkdirSync(project.config.dumpDir, { recursive: true })
  }
  project.vitest.state.metadata[project.name].dumpDir = project.config.dumpDir

  function getEnvironment(environmentName: string): DevEnvironment {
    const environment = project.vite.environments[environmentName]
    if (!environment) {
      throw new Error(`The environment ${environmentName} was not defined in the Vite config.`)
    }
    return environment
  }

  async function fetchModule(
    url: string,
    importer: string | undefined,
    environment: DevEnvironment,
    options?: FetchFunctionOptions,
    otelCarrier?: OTELCarrier,
    // per-module durations are only recorded for direct worker fetches: the
    // graph prewarm fetches whole levels concurrently, so its per-module wall
    // times measure the queue position, not the module's own transform cost
    accountModuleDuration = true,
  ): Promise<FetchResult | FetchCachedFileSystemResult> {
    const state = project.vitest.state
    const start = performance.now()

View on GitHub (pinned to 1fa9837ec2)