vitest-dev/vitest · error · TypeError

Test worker should expose "runTests" method. Received "${typ

Error message

Test worker should expose "runTests" method. Received "${typeof worker.runTests}".

What it means

Thrown by the runtime execute() dispatcher when the provided worker object does not expose a callable runTests (for 'run') or collectTests (for 'collect') method. The VitestWorker contract (packages/vitest/src/runtime/workers/types.ts) requires both runTests and collectTests functions, and this guard rejects workers that only partially implement it.

Source

Thrown at packages/vitest/src/runtime/worker.ts:59

        prepare: prepareStart,
      },
      rpc,
      onCancel,
      onCleanup: listeners.onCleanup,
      providedContext: ctx.providedContext,
      onFilterStackTrace(stack) {
        return createStackString(parseStacktrace(stack))
      },
      metaEnv: ctx.metaEnv,
      getterTracker: ctx.config.benchmark.enabled && !ctx.config.benchmark.suppressExportGetterWarnings
        ? new GetterTracker()
        : undefined,
    } satisfies WorkerGlobalState

    const methodName = method === 'collect' ? 'collectTests' : 'runTests'

    if (!worker[methodName] || typeof worker[methodName] !== 'function') {
      throw new TypeError(
        `Test worker should expose "runTests" method. Received "${typeof worker.runTests}".`,
      )
    }

    await worker[methodName](state, traces)
  }
  finally {
    await rpcDone().catch(() => {})
    await Promise.all(cleanups.map(fn => fn())).catch(() => {})
  }
}

export function run(ctx: ContextRPC, worker: VitestWorker, traces: Traces): Promise<void> {
  return execute('run', ctx, worker, traces)
}

export function collect(ctx: ContextRPC, worker: VitestWorker, traces: Traces): Promise<void> {
  return execute('collect', ctx, worker, traces)

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Ensure your custom worker object defines both runTests and collectTests as functions per the VitestWorker interface.
  2. Confirm you are passing the actual worker instance (not a prototype/options object) to runtime run()/collect().
  3. Re-export the standard worker init (init-threads/init-forks) which wires these methods automatically instead of hand-rolling them.

Example fix

// before: custom worker missing runTests
const worker = { post, on, off, serialize, deserialize }
runtime.run(ctx, worker, traces)

// after: provide the required methods
const worker = {
  post, on, off, serialize, deserialize,
  runTests: (state, traces) => runBaseTests('run', state, traces),
  collectTests: (state, traces) => runBaseTests('collect', state, traces),
}
runtime.run(ctx, worker, traces)
Defensive patterns

Strategy: type-guard

Type guard

import type { VitestWorker } from 'vitest/workers'

function isValidVitestWorker(w: unknown): w is VitestWorker {
  return !!w
    && typeof w === 'object'
    && typeof (w as any).runTests === 'function'
    && typeof (w as any).collectTests === 'function'
    && typeof (w as any).post === 'function'
    && typeof (w as any).on === 'function'
    && typeof (w as any).off === 'function'
}

if (!isValidVitestWorker(worker)) {
  throw new TypeError('worker is not a valid VitestWorker')
}

Prevention

When it happens

Trigger: Implementing a custom pool/worker via the experimental VitestWorker interface and passing a worker object that is missing the runTests method, has it set to undefined, or assigns a non-function value. Reached at runtime/worker.ts:58 inside execute() before any test runs.

Common situations: Writing a custom worker pool and forgetting to wire runTests/collectTests, or a build/bundling step that tree-shook the methods off the exported worker object, or passing the wrong object to the runtime run/collect entry points.

Related errors


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