vitest-dev/vitest · error · Error
Unable to parse thresholds from configuration file: ${messag
Error message
Unable to parse thresholds from configuration file: ${message} What it means
Outer wrapper at coverage.ts:869 — any error while reading thresholds from the config file (the inner check at 252, or a property-access failure on an undefined nested path) is rethrown with the 'Unable to parse thresholds from configuration file:' prefix and the inner message appended.
Source
Thrown at packages/vitest/src/node/coverage.ts:869
}
}
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') {
return mod
}
// "export default defineConfig(...)"
let config = resolveDefineConfig(mod)
if (config) {
return configView on GitHub (pinned to d568f8ce37)
Solutions
- Read the inner message after the colon — it identifies the actual problem (most often error 252).
- Ensure coverage.thresholds is an object in the config file.
- If autoUpdate is on, define thresholds in the file before enabling it.
Example fix
// before
export default defineConfig({ test: { coverage: { thresholds: { lines: NaN } } } })
// after
export default defineConfig({ test: { coverage: { thresholds: { lines: 80 } } } }) Defensive patterns
Strategy: try-catch
Validate before calling
try {
assertThresholdsShape(config)
} catch (e) {
throw new Error(`Thresholds parse failed: ${(e as Error).message}`)
} Type guard
function thresholdsParsed(t: unknown): t is Record<string, number> {
return t != null && typeof t === 'object' && !Array.isArray(t)
&& Object.values(t).every(v => typeof v === 'number')
} Try / catch
try { resolveThresholdsFromConfig(cfg) }
catch (e) {
const msg = (e as Error).message
if (msg.startsWith('Unable to parse thresholds')) handleConfigError(msg)
throw e
} Prevention
- Read the inner message after the prefix to find the real cause.
- Ensure thresholds is a well-formed object before enabling autoUpdate.
- Add a lint-time check for the thresholds shape.
When it happens
Trigger: Anything that throws inside the thresholds parse block: thresholds is a non-object, or test/coverage nested paths are missing in the parsed config file.
Common situations: Misconfigured thresholds; autoUpdate running against a config file that doesn't define coverage.thresholds at all.
Related errors
- Missing configurationFile. The "coverage.thresholds.autoUpda
- ${error instanceof Error ? error.message : String(error)}
- Failed to update coverage thresholds. Configuration file is
- 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/ec9c2d9eccb496cc.json.
Report an issue: GitHub.