vitest-dev/vitest · error · Error
${error instanceof Error ? error.message : String(error)}
Error message
${error instanceof Error ? error.message : String(error)} What it means
resolveConfig (coverage.ts:900) catches magicast errors while statically analyzing the config AST and rethrows just the message. This is the generic fallback for any unparseable shape while walking defineConfig/mergeConfig/inline-object forms during the autoUpdate flow.
Source
Thrown at packages/vitest/src/node/coverage.ts:900
}
// "export default defineConfig(...)"
let config = resolveDefineConfig(mod)
if (config) {
return config
}
// "export default mergeConfig(..., defineConfig(...))"
if (mod.$type === 'function-call' && mod.$callee === 'mergeConfig') {
config = resolveMergeConfig(mod)
if (config) {
return config
}
}
}
catch (error) {
// Reduce magicast's verbose errors to readable ones
throw new Error(error instanceof Error ? error.message : String(error))
}
throw new Error(
'Failed to update coverage thresholds. Configuration file is too complex.',
)
}
function resolveDefineConfig(mod: any) {
if (mod.$type === 'function-call' && mod.$callee === 'defineConfig') {
// "export default defineConfig({ test: {...} })"
if (mod.$args[0].$type === 'object') {
return mod.$args[0]
}
if (mod.$args[0].$type === 'arrow-function-expression') {
if (mod.$args[0].$body.$type === 'object') {
// "export default defineConfig(() => ({ test: {...} }))"
return mod.$args[0].$bodyView on GitHub (pinned to d568f8ce37)
Solutions
- Simplify the config so thresholds sit inside a plain export default defineConfig({ test: { coverage: { thresholds: {...} } } }).
- Move dynamic logic out of the config file (env-based branching, etc.).
- Disable autoUpdate and update thresholds manually if the config must stay dynamic.
Example fix
// before
export default defineConfig(() => buildConfig(env))
// after
export default defineConfig({ test: { coverage: { thresholds: { lines: 80 } } } }) Defensive patterns
Strategy: fallback
Validate before calling
try {
await reporter.updateThresholds(...)
} catch (e) {
console.warn('Static config rewrite failed; falling back to manual thresholds')
} Type guard
function isStaticallyParseable(ast: any): boolean {
return ast?.exports?.default?.$type === 'object'
|| ast?.exports?.default?.$callee === 'defineConfig'
|| ast?.exports?.default?.$callee === 'mergeConfig'
} Try / catch
try { resolveConfig(mod) }
catch (e) { throw new Error(`Config too dynamic to rewrite thresholds: ${(e as Error).message}`) } Prevention
- Keep the config file static and standard (export default defineConfig({...})).
- Move dynamic/conditional logic out of the config file.
- Disable autoUpdate if the config must stay dynamic.
When it happens
Trigger: A config file whose AST magicast cannot statically resolve — computed property keys, dynamic imports, runtime-spread conditionals, calls to unknown helper functions.
Common situations: Highly dynamic config files; configs that wrap defineConfig in custom helpers; configs that build the test object conditionally at runtime.
Related errors
- Failed to update coverage thresholds. Configuration file is
- Missing configurationFile. The "coverage.thresholds.autoUpda
- Unable to parse thresholds from configuration file: ${messag
- BaseReporter's parseConfigModule was not overwritten
- Expected config.test.coverage.thresholds to be an object
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/d73076eb59571ae9.json.
Report an issue: GitHub.