angular/angular-cli · warning

Project "${projectName}" uses a custom coverage reporter "${

Error message

Project "${projectName}" uses a custom coverage reporter "${type}". This reporter cannot be automatically mapped to Vitest. Please check the Vitest documentation for equivalent coverage reporters.

What it means

During the Karma-to-Vitest migration, extractCoverageSettings maps Karma coverage reporters to Vitest-supported ones. When a karma.conf.js declares a coverage reporter type not in SUPPORTED_COVERAGE_REPORTERS, this warning tells you the reporter cannot be auto-mapped and you must pick an equivalent Vitest/istanbul reporter yourself.

Source

Thrown at packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-processor.ts:86

  // Extract coverage reporters
  const covReporters = (coverageReporter as Record<string, unknown>)['reporters'];
  if (Array.isArray(covReporters)) {
    const mappedCovReporters: string[] = [];
    for (const r of covReporters) {
      let type: string | undefined;
      if (typeof r === 'object' && r !== null && 'type' in r) {
        if (typeof r['type'] === 'string') {
          type = r['type'];
        }
      } else if (typeof r === 'string') {
        type = r;
      }

      if (type) {
        if (SUPPORTED_COVERAGE_REPORTERS.has(type)) {
          mappedCovReporters.push(type);
        } else {
          context.logger.warn(
            `Project "${projectName}" uses a custom coverage reporter "${type}". ` +
              `This reporter cannot be automatically mapped to Vitest. ` +
              `Please check the Vitest documentation for equivalent coverage reporters.`,
          );
        }
      }
    }
    if (mappedCovReporters.length > 0) {
      options['coverageReporters'] = [...new Set(mappedCovReporters)];
    }
  }

  // Extract coverage thresholds
  const check = (coverageReporter as Record<string, unknown>)['check'];
  if (typeof check === 'object' && check !== null) {
    const global = (check as Record<string, unknown>)['global'];
    if (typeof global === 'object' && global !== null) {
      const thresholds: Record<string, number> = {};

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Open the project's karma.conf.js and note the custom coverageReporter.type
  2. Set an equivalent supported reporter in the generated Vitest coverage config (e.g. via vitest-base.config.ts or the test builder's coverageReporters option: ['html','lcov','text'])
  3. Replace CI-specific reporters with nyc/istanbul equivalents supported by Vitest (e.g. cobertura -> 'clover'/'lcov' plus a conversion step, teamcity -> 'text' parsed by CI)
  4. Re-run or complete the migration and verify coverage output matches your CI expectations

Example fix

// before (karma.conf.js)
coverageReporter: { type: 'teamcity' }
// after (vitest config / builder options)
test: { coverage: { reporter: ['text', 'lcov'] } }
Defensive patterns

Strategy: validation

Validate before calling

// before migrating, check your karma reporters
const types = (karmaConfig.coverageReporter?.type || []);
const supported = new Set(['clover','cobertura','lcov','lcovonly','html','json','json-summary','text','text-summary','teamcity','none']);
const unsupported = [].concat(types).filter(t => !supported.has(t));
if (unsupported.length) console.warn('Manual coverage reporter mapping needed:', unsupported);

Prevention

When it happens

Trigger: Running the migrate-karma-to-vitest migration (via processKarmaConfig -> extractCoverageSettings) on a project whose karma.conf.js coverageReporter.type is a custom value not in the supported set (e.g. 'json-summary' variants, 'lcovonly', 'teamcity', or custom reporter names).

Common situations: Projects with customized karma-coverage setups (html+lcovonly combos, CI-specific reporters like teamcity or cobertura, third-party reporters) migrating from Karma/ Jasmine to Vitest on Angular CLI upgrades.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/b18126f04296b786. Report an issue: GitHub.