vitejs/vite · error · Error
Cannot merge config in form of callback
Error message
Cannot merge config in form of callback
What it means
Vite's mergeConfig merges two already-resolved plain config objects recursively. It explicitly rejects either argument being a function because config 'callbacks' (the defineConfig(() => {}) form) are meant to be resolved/awaited before merging — merging unresolved callback forms is undefined. Passing a function as either defaults or overrides indicates the caller bypassed the env/mode resolution step.
Source
Thrown at packages/vite/src/node/utils.ts:1575
)
continue
}
merged[key] = value
}
return merged
}
export function mergeConfig<
D extends Record<string, any>,
O extends Record<string, any>,
>(
defaults: D extends Function ? never : D,
overrides: O extends Function ? never : O,
isRoot = true,
): Record<string, any> {
if (typeof defaults === 'function' || typeof overrides === 'function') {
throw new Error(`Cannot merge config in form of callback`)
}
return mergeConfigRecursively(defaults, overrides, isRoot ? '' : '.')
}
function mergeInput(a?: InputOption, b?: InputOption): InputOption | undefined {
if (!a) return b
if (!b) return a
if (typeof a === 'string' && typeof b === 'string') {
return [a, b]
}
if (Array.isArray(a) && (typeof b === 'string' || Array.isArray(b))) {
return [...a, ...(Array.isArray(b) ? b : [b])]
}
if (Array.isArray(b) && (typeof a === 'string' || Array.isArray(a))) {
return [...(Array.isArray(a) ? a : [a]), ...b]
}View on GitHub (pinned to 89620f09af)
Solutions
- Resolve the callback first: call the function with ({ mode, command }) to get a plain object, then pass that to mergeConfig.
- Export the base config as a plain object (not the callback form of defineConfig) if it will be merged programmatically.
- Use defineConfig's built-in merging or the loadConfig/resolveConfig pipeline so callbacks are resolved before mergeConfig runs.
Example fix
// before — passing the callback form to mergeConfig
const base = defineConfig(() => ({ plugins: [a] }))
const merged = mergeConfig(base, { plugins: [b] })
// after — resolve the callback, then merge plain objects
const baseResolved = await (base as any)({ mode: 'development', command: 'serve' })
const merged = mergeConfig(baseResolved, { plugins: [b] }) Defensive patterns
Strategy: validation
Validate before calling
// Ensure neither argument is a function before merging
if (typeof defaults === 'function' || typeof overrides === 'function') {
throw new Error('Resolve defineConfig callbacks to plain objects before mergeConfig')
}
const merged = mergeConfig(defaults, overrides) Type guard
function isPlainConfig(v: unknown): v is Record<string, any> {
return v != null && typeof v === 'object' && typeof v !== 'function'
} Prevention
- Always resolve defineConfig(() => ...) callbacks to plain objects before mergeConfig.
- Export shared base configs as plain objects, not callback forms, when they will be merged.
- Run mergeConfig only on already-resolved config objects from resolveConfig/loadConfig.
When it happens
Trigger: Calling mergeConfig(defineConfig(() => ({...})), {...}) or mergeConfig({...}, defineConfig(() => ({...}))) directly — i.e. passing the function form of defineConfig (or any function) as an argument. This happens when merging configs programmatically without first resolving the callback.
Common situations: Writing a plugin or framework layer that merges Vite configs and accidentally passes the defineConfig callback form instead of its resolved output. Combining a shared base config (exported as a callback) with an override config via mergeConfig. Copy-pasting from a config file that uses defineConfig(() => ...) into a mergeConfig call site.
Related errors
- { runtime: "${result.runtime}" } is not supported for assets
- `renderLegacyChunks` and `renderModernChunks` cannot be both
- @vitejs/plugin-legacy does not support library mode.
- HMR is not supported by this runner transport, but `hmr` opt
- Invalid environment name "${name}". Environment names must o
AI-assisted analysis of vitejs/vite@89620f09af (2026-08-03).
Data as JSON: /data/errors/ccfbbd300b9a0876.json.
Report an issue: GitHub.