vitest-dev/vitest · error · Error

Failed to load custom "defines": ${error.message}

Error message

Failed to load custom "defines": ${error.message}

What it means

Vitest injects user-defined `define` replacements as serialized JS and evaluates them via node:vm runInThisContext during base environment setup (base.ts:91-100). If that generated code is syntactically invalid or throws at runtime, the original error is wrapped and rethrown with this message naming the define failure.

Source

Thrown at packages/vitest/src/runtime/workers/base.ts:99

  const startTime = performance.now()
  const {
    environment: { name: environmentName, options: environmentOptions },
    rpc,
    config,
  } = context

  setupEnv(config.env, context.metaEnv)

  // we could load @vite/env, but it would take ~8ms, while this takes ~0,02ms
  if (context.config.serializedDefines) {
    try {
      runInThisContext(`(() =>{\n${context.config.serializedDefines}})()`, {
        lineOffset: 1,
        filename: 'virtual:load-defines.js',
      })
    }
    catch (error: any) {
      throw new Error(`Failed to load custom "defines": ${error.message}`)
    }
  }
  const otel = context.traces

  const { environment, loader } = await loadEnvironment(
    environmentName,
    config.root,
    rpc,
    otel,
    context.config.experimental.viteModuleRunner,
  )
  _currentEnvironment = environment
  const env = await otel.$(
    'vitest.runtime.environment.setup',
    {
      attributes: {
        'vitest.environment': environment.name,
        'vitest.environment.vite_environment': environment.viteEnvironment || environment.name,

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Use JSON.stringify on define values so they serialize as valid JS literals.
  2. Simplify define to a single key/value and re-add entries to isolate which one produces invalid code.
  3. Check the inner error.message (appended after 'Failed to load custom "defines":') for the exact syntax/runtime cause.

Example fix

// before: object value serializes to [object Object]
define: { 'import.meta.env.cfg': { a: 1 } }

// after: stringify the value
define: { 'import.meta.env.cfg': JSON.stringify({ a: 1 }) }
Defensive patterns

Strategy: validation

Validate before calling

function validateDefines(defines: Record<string, unknown>) {
  for (const [key, value] of Object.entries(defines)) {
    const serialized = typeof value === 'string' ? value : JSON.stringify(value)
    try {
      // wrap in expression position to mimic vitest's define injection
      new Function(`return (${serialized})`)
    } catch (e) {
      throw new Error(`Invalid define for '${key}': ${(e as Error).message}`)
    }
  }
}

Prevention

When it happens

Trigger: Configuring test.define (or vite define) with values whose serialized form produces invalid JavaScript, e.g. a define value that is not properly JSON-stringified, a string value inserted without quotes, or a define referencing an undefined variable. Reached when config.serializedDefines is truthy and runInThisContext throws.

Common situations: Setting define: { 'import.meta.env.FOO': someVariable } where someVariable is an object/function that serializes to invalid code; passing a raw string without JSON.stringify; a define key/value pair that produces a syntax error when spliced into an IIFE.

Related errors


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