vitest-dev/vitest · error · TypeError

Environment doesn't provide a valid context. It should be…

Error message

Environment ${environment.name} doesn't provide a valid context. It should be created by "vm.createContext" method.

What it means

Even when getVmContext exists, Vitest calls it and passes the result to vm.isContext(). If that returns false (the value was not created by vm.createContext), it throws a TypeError stating the environment did not provide a valid context. This guards against environments returning a plain object, null, or a reused/disposed context.

Solutions

  1. Ensure getVmContext returns the exact value returned by vm.createContext() (store it, return it).
  2. Do not dispose or recreate the context between setup and getVmContext.
  3. Add a guard in the environment: if (!vm.isContext(ctx)) throw before returning.
  4. Upgrade the environment package; this is a contract bug in the environment.

Example fix

// before
getVmContext() { return this.sandbox /* plain object */ }

// after
const ctx = vm.createContext(this.sandbox)
getVmContext() { return ctx }
Defensive patterns

Strategy: validation

Validate before calling

import vm from 'node:vm'
const ctx = environment.getVmContext()
if (!vm.isContext(ctx)) throw new Error('not a vm context')

Type guard

function isValidVmContext(ctx) {
  return require('node:vm').isContext(ctx)
}

Prevention

When it happens

Trigger: environment.getVmContext() returns something that is not a real vm context — e.g. a plain object, a Proxy, null, or a context that was already disposed. vm.isContext() is the canonical check for a context created via vm.createContext.

Common situations: A custom environment whose getVmContext returns a global object or a sandbox object that was never passed through vm.createContext; returning undefined accidentally; or a context disposed in a previous run being reused.

Related errors


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

Appendix: source

Thrown at packages/vitest/src/runtime/workers/vm.ts:84

      },
    },
    () => environment.setupVM!(ctx.environment.options || ctx.config.environmentOptions || {}),
  )

  state.durations.environment = performance.now() - beforeEnvironmentTime

  process.env.VITEST_VM_POOL = '1'

  if (!vm.getVmContext) {
    throw new TypeError(
      `Environment ${environment.name} doesn't provide "getVmContext" method. It should return a context created by "vm.createContext" method.`,
    )
  }

  const context: Context | null = vm.getVmContext()

  if (!isContext(context)) {
    throw new TypeError(
      `Environment ${environment.name} doesn't provide a valid context. It should be created by "vm.createContext" method.`,
    )
  }

  // captured before vitest installs its own globals (worker state, console,
  // mocker, executor symbol): they reference the test file's module graph, so
  // the teardown strip must treat them as removable, not as pristine
  const initialContextKeys = captureContextKeys(context)

  provideWorkerState(context, state)

  // this is unfortunately needed for our own dependencies
  // we need to find a way to not rely on this by default
  // because browser doesn't provide these globals
  context.process = process
  context.global = context
  context.console = state.config.disableConsoleIntercept
    ? console

View on GitHub (pinned to 1fa9837ec2)