vitest-dev/vitest · error · Error

[@vitest/web-worker] Cannot initiate a custom Web Worker. "$

Error message

[@vitest/web-worker] Cannot initiate a custom Web Worker. "${name}" is not supported in this environment. Please, consider using jsdom or happy-dom environment.

What it means

defineWebWorkers (packages/web-worker/src/pure.ts:6-24) installs the Worker/SharedWorker constructors only when the current runtime lacks them. Before installing, it calls assertGlobalExists('EventTarget') and assertGlobalExists('MessageEvent') (utils.ts:8-14) because Vitest's worker shim is built on top of those primitives. If the named global is missing from globalThis, the function throws this Error telling the user which environment primitives are unavailable.

Source

Thrown at packages/web-worker/src/utils.ts:10

import type { Debugger } from 'obug'
import type { CloneOption } from './types'
import ponyfillStructuredClone from '@ungap/structured-clone'
import { createDebug } from 'obug'

export const debug: Debugger = createDebug('vitest:web-worker')

export function assertGlobalExists(name: string): void {
  if (!(name in globalThis)) {
    throw new Error(
      `[@vitest/web-worker] Cannot initiate a custom Web Worker. "${name}" is not supported in this environment. Please, consider using jsdom or happy-dom environment.`,
    )
  }
}

function createClonedMessageEvent(
  data: any,
  transferOrOptions: StructuredSerializeOptions | Transferable[] | undefined,
  clone: CloneOption,
) {
  const transfer = Array.isArray(transferOrOptions)
    ? transferOrOptions
    : transferOrOptions?.transfer

  debug('clone worker message %o', data)
  const origin = typeof location === 'undefined' ? undefined : location.origin
  const ports = transfer?.filter((t): t is MessagePort => t instanceof MessagePort)

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Set the test environment to a DOM-providing one in vitest.config.ts: `test: { environment: 'happy-dom' }` (or 'jsdom').
  2. Install the missing environment package if not present (`npm i -D jsdom` or `npm i -D @happy-dom/global-registrator`).
  3. If you intentionally run in node, ensure your setup file polyfills EventTarget and MessageEvent on globalThis before calling defineWebWorkers.
  4. Confirm the environment name in config is spelled correctly — a typo silently falls back to node and trips this assertion.

Example fix

// before — vitest.config.ts
import { defineConfig } from 'vitest/config'
export default defineConfig({
  test: { environment: 'node', setupFiles: ['@vitest/web-worker'] },
})

// after — provide EventTarget + MessageEvent via a DOM environment
import { defineConfig } from 'vitest/config'
export default defineConfig({
  test: { environment: 'happy-dom', setupFiles: ['./setup.ts'] },
})
// setup.ts
import { defineWebWorkers } from '@vitest/web-worker'
defineWebWorkers()
Defensive patterns

Strategy: validation

Validate before calling

// Verify the environment has the globals defineWebWorkers needs BEFORE
// importing @vitest/web-worker. Mirrors utils.ts assertGlobalExists.
function canDefineWebWorkers() {
  return (
    typeof globalThis !== 'undefined' &&
    'EventTarget' in globalThis &&
    'MessageEvent' in globalThis
  )
}
if (!canDefineWebWorkers()) {
  throw new Error(
    'Set test.environment to happy-dom or jsdom before using @vitest/web-worker.',
  )
}

Prevention

When it happens

Trigger: Calling `import { defineWebWorkers } from '@vitest/web-worker'` followed by `defineWebWorkers()` (often via the `@vitest/web-worker` browser plugin or setup file) while the test `environment` is set to 'node' or any environment that does not expose EventTarget/MessageEvent on globalThis. The check runs at setup time, so the error surfaces as soon as the web-worker plugin initializes.

Common situations: Forgetting to set `test.environment: 'happy-dom'` or `'jsdom'` in vitest.config when tests use web workers; switching a project's environment from jsdom to node to speed up tests and forgetting the worker setup; running in a minimal custom environment that polyfills fetch but not EventTarget/MessageEvent; version upgrade that moved the defineWebWorkers call earlier in setup.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/1e58dce6ca900be2.json. Report an issue: GitHub.