vitest-dev/vitest · error · TypeError
Expected config.test.coverage.thresholds to be an object
Error message
Expected config.test.coverage.thresholds to be an object
What it means
resolveThresholds (coverage.ts:862) asserts that config.test.coverage.thresholds is an object before reading its keys. Anything else (boolean, array, number, undefined when autoUpdate walks the config file) throws a TypeError.
Source
Thrown at packages/vitest/src/node/coverage.ts:862
'functions' in thresholds && typeof thresholds.functions === 'number'
? thresholds.functions
: undefined,
statements:
'statements' in thresholds && typeof thresholds.statements === 'number'
? thresholds.statements
: undefined,
}
}
function assertConfigurationModule(config: unknown): asserts config is {
test: {
coverage: { thresholds: NonNullable<CoverageOptions['thresholds']> }
}
} {
try {
// @ts-expect-error -- Intentional unsafe null pointer check as wrapped in try-catch
if (typeof config.test.coverage.thresholds !== 'object') {
throw new TypeError(
'Expected config.test.coverage.thresholds to be an object',
)
}
}
catch (error) {
const message = error instanceof Error ? error.message : String(error)
throw new Error(
`Unable to parse thresholds from configuration file: ${message}`,
)
}
}
function resolveConfig(configModule: any) {
const mod = configModule.exports.default
try {
// Check for "export default { test: {...} }"
if (mod.$type === 'object') {View on GitHub (pinned to d568f8ce37)
Solutions
- Set coverage.thresholds to an object, e.g. { lines: 80, functions: 80, branches: 75, statements: 80 }.
- Remove the thresholds key entirely if you don't enforce thresholds.
- Re-run after fixing; the message tells you exactly what failed.
Example fix
// before
test: { coverage: { thresholds: true } }
// after
test: { coverage: { thresholds: { lines: 80, functions: 80 } } } Defensive patterns
Strategy: type-guard
Validate before calling
const t = config.test?.coverage?.thresholds
if (t != null && (typeof t !== 'object' || Array.isArray(t))) {
throw new TypeError('coverage.thresholds must be an object')
} Type guard
function isThresholdsObject(t: unknown): t is Record<string, number> {
return t != null && typeof t === 'object' && !Array.isArray(t)
} Prevention
- Define thresholds as an object { lines, functions, branches, statements }.
- Validate the config with a schema/zod check in CI.
- Avoid shorthand like thresholds: true.
When it happens
Trigger: Config file (or magicast-parsed module) has coverage.thresholds set to a non-object value such as true, null, or an array, and vitest tries to read/update thresholds from it.
Common situations: Setting thresholds: true as a shortcut; copying partial config from docs; autoUpdate walking a misshapen config.
Related errors
- Missing configurationFile. The "coverage.thresholds.autoUpda
- Unable to parse thresholds from configuration file: ${messag
- ${error instanceof Error ? error.message : String(error)}
- Failed to update coverage thresholds. Configuration file is
- Environment "${name}" is not a valid environment. Path "${pa
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/f57d458d6aa74c9e.json.
Report an issue: GitHub.