{"id":"ec9c2d9eccb496cc","repo":"vitest-dev/vitest","slug":"unable-to-parse-thresholds-from-configuration-file","errorCode":null,"errorMessage":"Unable to parse thresholds from configuration file: ${message}","messagePattern":"Unable to parse thresholds from configuration file: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/coverage.ts","lineNumber":869,"sourceCode":"  }\n}\n\nfunction assertConfigurationModule(config: unknown): asserts config is {\n  test: {\n    coverage: { thresholds: NonNullable<CoverageOptions['thresholds']> }\n  }\n} {\n  try {\n    // @ts-expect-error -- Intentional unsafe null pointer check as wrapped in try-catch\n    if (typeof config.test.coverage.thresholds !== 'object') {\n      throw new TypeError(\n        'Expected config.test.coverage.thresholds to be an object',\n      )\n    }\n  }\n  catch (error) {\n    const message = error instanceof Error ? error.message : String(error)\n    throw new Error(\n      `Unable to parse thresholds from configuration file: ${message}`,\n    )\n  }\n}\n\nfunction resolveConfig(configModule: any) {\n  const mod = configModule.exports.default\n\n  try {\n    // Check for \"export default { test: {...} }\"\n    if (mod.$type === 'object') {\n      return mod\n    }\n\n    // \"export default defineConfig(...)\"\n    let config = resolveDefineConfig(mod)\n    if (config) {\n      return config","sourceCodeStart":851,"sourceCodeEnd":887,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/node/coverage.ts#L851-L887","documentation":"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.","triggerScenarios":"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.","commonSituations":"Misconfigured thresholds; autoUpdate running against a config file that doesn't define coverage.thresholds at all.","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."],"exampleFix":"// before\nexport default defineConfig({ test: { coverage: { thresholds: { lines: NaN } } } })\n\n// after\nexport default defineConfig({ test: { coverage: { thresholds: { lines: 80 } } } })","handlingStrategy":"try-catch","validationCode":"try {\n  assertThresholdsShape(config)\n} catch (e) {\n  throw new Error(`Thresholds parse failed: ${(e as Error).message}`)\n}","typeGuard":"function thresholdsParsed(t: unknown): t is Record<string, number> {\n  return t != null && typeof t === 'object' && !Array.isArray(t)\n  && Object.values(t).every(v => typeof v === 'number')\n}","tryCatchPattern":"try { resolveThresholdsFromConfig(cfg) }\ncatch (e) {\n  const msg = (e as Error).message\n  if (msg.startsWith('Unable to parse thresholds')) handleConfigError(msg)\n  throw e\n}","preventionTips":["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."],"tags":["coverage","thresholds","config","autoupdate"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}