vitest-dev/vitest · error · Error

[vitest] "registerHooks" is not available when running in…

Error message

[vitest] "registerHooks" is not available when running in Vitest.

What it means

Thrown by the stub `Module.registerHooks` static method on the fake CommonJS Module class inside Vitest's vm executor. registerHooks is Node's companion to module.register for setting hook callbacks; Vitest deliberately disables it because it manages its own module pipeline inside workers, and surfaces an explicit error instead of a silent no-op.

Solutions

  1. Gate the call so it does not run under Vitest: `if (!process.env.VITEST) Module.registerHooks(...)`.
  2. Mock or exclude the module that performs registration in your test setup.
  3. Use Vitest-native extension points (server.mode, deps.inline, plugins) instead of Node loader hooks.
  4. Move the registration into a separate process spawned by the test if the hook behavior must be exercised.

Example fix

// before
import Module from 'node:module'
Module.registerHooks({ load() { /* ... */ } })

// after
import Module from 'node:module'
if (!process.env.VITEST) {
  Module.registerHooks({ load() { /* ... */ } })
}
Defensive patterns

Strategy: validation

Validate before calling

const isVitest = !!process.env.VITEST
if (!isVitest) {
  await import('node:module').then(m => m.registerHooks({ load() { /* ... */ } }))
}

Type guard

function shouldSkipModuleRegisterHooks(): boolean {
  return !!process.env.VITEST
}

Try / catch

try {
  Module.registerHooks(hooks)
} catch (e) {
  if (String(e?.message).includes('"registerHooks" is not available when running in Vitest')) {
    // expected under Vitest
  } else throw e
}

Prevention

When it happens

Trigger: Code under test (executed through Vitest's vm/commonjs executor) calls `module.registerHooks(...)` or `Module.registerHooks(...)` — typically a library that wires up ESM loader hooks for tracing, instrumentation, or transpilation.

Common situations: Testing instrumentation/tracing SDKs that register hooks at import time; porting code that relied on Node's loader hook APIs into a Vitest suite; running under the default pools that use the vm CommonJS executor.

Related errors


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

Appendix: source

Thrown at packages/vitest/src/runtime/vm/commonjs-executor.ts:140

      static getSourceMapsSupport = () => ({
        enabled: false,
        nodeModules: false,
        generatedCode: false,
      })

      static setSourceMapsSupport = () => {
        // noop
      }

      static register = () => {
        throw new Error(
          `[vitest] "register" is not available when running in Vitest.`,
        )
      }

      static registerHooks = () => {
        throw new Error(
          `[vitest] "registerHooks" is not available when running in Vitest.`,
        )
      }

      _compile(code: string, filename: string) {
        const cjsModule = Module.wrap(code)
        const codeCache = executor.codeCache
        let script = cjsScriptCache.get(filename)
        if (!script) {
          const cachedData = codeCache?.get(filename, cjsModule)
          // the dynamic import callback is a static function (the executor is
          // resolved when it is called), so the compiled script holds no
          // per-context state and can be reused by every vm context
          try {
            script = new vm.Script(cjsModule, {
              filename,
              cachedData,
              importModuleDynamically: activeImportModuleDynamically,

View on GitHub (pinned to 1fa9837ec2)