{"id":"3233b505db8f39b2","repo":"vitest-dev/vitest","slug":"missing-configurationfile-the-coverage-threshold","errorCode":null,"errorMessage":"Missing configurationFile. The \"coverage.thresholds.autoUpdate\" can only be enabled when configuration file is used.","messagePattern":"Missing configurationFile\\. The \"coverage\\.thresholds\\.autoUpdate\" can only be enabled when configuration file is used\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/coverage.ts","lineNumber":409,"sourceCode":"      (coverageMap as CoverageMap) || this.createCoverageMap(),\n      allTestsRun,\n    )\n\n    // In watch mode we need to preserve the previous results if cleanOnRerun is disabled\n    const keepResults = !this.options.cleanOnRerun && this.ctx.config.watch\n\n    if (!keepResults) {\n      await this.cleanAfterRun()\n    }\n  }\n\n  async reportThresholds(coverageMap: CoverageMap, allTestsRun: boolean | undefined): Promise<void> {\n    const resolvedThresholds = this.resolveThresholds(coverageMap)\n    this.checkThresholds(resolvedThresholds)\n\n    if (this.options.thresholds?.autoUpdate && allTestsRun) {\n      if (!this.ctx.vite.config.configFile) {\n        throw new Error(\n          'Missing configurationFile. The \"coverage.thresholds.autoUpdate\" can only be enabled when configuration file is used.',\n        )\n      }\n\n      const configFilePath = this.ctx.vite.config.configFile\n      const configModule = await this.parseConfigModule(configFilePath)\n\n      await this.updateThresholds({\n        thresholds: resolvedThresholds,\n        configurationFile: configModule,\n        onUpdate: () =>\n          writeFileSync(\n            configFilePath,\n            configModule.generate().code.replace(this.autoUpdateMarker, ''),\n            'utf-8',\n          ),\n\n      })","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/node/coverage.ts#L391-L427","documentation":"coverage.thresholds.autoUpdate (coverage.ts:409) rewrites threshold numbers inside the user's config file, so it requires an actual config file on disk. When vite.config.configFile is null (config supplied inline or purely via CLI flags) vitest has nothing to rewrite and throws.","triggerScenarios":"Enabling coverage.thresholds.autoUpdate while running vitest configless — passing config inline via createVitest() or relying only on CLI flags, so no vitest.config.* / vite.config.* is resolved.","commonSituations":"Programmatic users passing a config object; CI that builds a config dynamically and never writes a file; examples using inline config.","solutions":["Create a vitest.config.ts (or vite.config.ts) on disk and enable autoUpdate there.","Disable coverage.thresholds.autoUpdate for configless/inline runs.","Write the inline config out to a temp file if autoUpdate is required."],"exampleFix":"// before\ncreateVitest('test', { test: { coverage: { thresholds: { autoUpdate: true } } } })\n\n// after\ncreateVitest('test', { configFile: './vitest.config.ts' })\n// and in vitest.config.ts set test.coverage.thresholds.autoUpdate = true","handlingStrategy":"validation","validationCode":"if (config.coverage.thresholds.autoUpdate && !viteConfig.configFile) {\n  throw new Error('autoUpdate requires a config file on disk')\n}","typeGuard":"function hasConfigFile(config: ResolvedConfig): boolean {\n  return Boolean(config.configFile)\n}","tryCatchPattern":null,"preventionTips":["Keep a vitest.config.* file on disk when using thresholds.autoUpdate.","Don't enable autoUpdate for inline/programmatic configless runs.","Write dynamic config to a temp file if autoUpdate is mandatory."],"tags":["coverage","thresholds","autoupdate","config"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}