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
- Use JSON.stringify on define values so they serialize as valid JS literals.
- Simplify define to a single key/value and re-add entries to isolate which one produces invalid code.
- 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
- Always JSON.stringify non-primitive define values in config.
- Keep define values static literals (strings, numbers, booleans, JSON).
- Add a smoke test that boots Vitest with the define config before running the full suite.
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
- Failed to load custom "defines": ${error.message}
- You've enabled headless mode for "preview" provider but it d
- vitest/browser can be imported only inside the Browser Mode.
- ${name}Browser name is required. Please, set `test.browser.i
- Browser Mode requires the "provider" to always be specified.
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/50c0eaeca8f6e8e2.json.
Report an issue: GitHub.