vitest-dev/vitest · error

Failed to update coverage thresholds. Configuration file is…

Error message

Failed to update coverage thresholds. Configuration file is too complex.

What it means

Final fallback in resolveConfig: none of the recognized config shapes matched (plain object, defineConfig call with object/arrow body, mergeConfig call). autoUpdate cannot statically rewrite thresholds, so it reports the config is too complex.

Solutions

  1. Restructure the default export to defineConfig({ test: { coverage: { thresholds } } }).
  2. Disable coverage.thresholds.autoUpdate and update thresholds manually.
  3. Use mergeConfig to layer configs (it is one of the recognized shapes).

Example fix

// before
export default buildConfig(env) // custom helper

// after
export default defineConfig({
  test: { coverage: { thresholds: { lines: 80 } } }
})
Defensive patterns

Strategy: fallback

Validate before calling

function configShapeSupported(mod) {
  if (mod.$type === 'object') return true
  if (mod.$type === 'function-call' && (mod.$callee === 'defineConfig' || mod.$callee === 'mergeConfig')) return true
  return false
}
// before autoUpdate: if (!configShapeSupported(parsed)) fall back to manual threshold update

Prevention

When it happens

Trigger: autoUpdate on a config whose default export is neither a literal object, a defineConfig(...), nor a mergeConfig(...) — e.g. a bare function, a re-export, a class instance, or a conditional expression.

Common situations: Configs like `export default condition ? a : b`; configs wrapped in custom helpers; configs that re-export from another module.

Related errors


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

Appendix: source

Thrown at packages/vitest/src/node/coverage.ts:903

    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].$body
      }

      // "export default defineConfig(() => mergeConfig({...}, ...))"

View on GitHub (pinned to 1fa9837ec2)