angular/angular-cli · warning

Project "${projectName}" has a non-string reporter in Karma

Error message

Project "${projectName}" has a non-string reporter in Karma config. This cannot be automatically mapped to Vitest.

What it means

Warning from extractReporters in karma-processor.ts. The migration expects karma.conf.js `reporters` entries to be plain strings; if an entry is not a string (e.g. an array-style multi-reporter entry, an object, or a function returned by a custom framework), it cannot be mapped and is skipped with this warning.

Source

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

          mappedReporters.push('default');
        } else if (r === 'kjhtml') {
          context.logger.warn(
            `Project "${projectName}" uses the "kjhtml" reporter. ` +
              `This has not been automatically mapped. ` +
              `For an interactive test UI in Vitest, consider setting the "ui" option to true in your test target options ` +
              `and installing "@vitest/ui".`,
          );
        } else if (SUPPORTED_REPORTERS.has(r)) {
          mappedReporters.push(r);
        } else {
          context.logger.warn(
            `Project "${projectName}" uses a custom Karma reporter "${r}". ` +
              `This reporter cannot be automatically mapped to Vitest. ` +
              `Please check the Vitest documentation for equivalent reporters.`,
          );
        }
      } else {
        context.logger.warn(
          `Project "${projectName}" has a non-string reporter in Karma config. ` +
            `This cannot be automatically mapped to Vitest.`,
        );
      }
    }
    if (mappedReporters.length > 0) {
      options['reporters'] = [...new Set(mappedReporters)];
    }
  }
}

function extractCoverageSettings(
  analysis: KarmaConfigAnalysis,
  options: Record<string, json.JsonValue | undefined>,
  projectName: string,
  context: SchematicContext,
): void {
  const coverageReporter = analysis.settings.get('coverageReporter');

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Flatten the reporters array to plain strings in karma.conf.js before migrating so entries can be mapped.
  2. Replace object/function reporter registrations with supported string reporter names.
  3. Remove the non-string entries if the reporters are no longer needed and re-run the migration.
  4. After migration, manually add equivalent Vitest reporters/plugins in the generated config.

Example fix

// before (karma.conf.js)
reporters: ['progress', ['junit', { outputDir: 'reports' }]],
// after
reporters: ['progress', 'junit'], // junit options moved to junitReporter config
Defensive patterns

Strategy: validation

Validate before calling

const reporters = karmaConfig?.reporters ?? [];
if (reporters.some(r => typeof r !== 'string')) {
  console.warn('reporters contains non-string entries; flatten before migrating');
}

Type guard

function allStringReporters(reporters: unknown): reporters is string[] {
  return Array.isArray(reporters) && reporters.every(r => typeof r === 'string');
}

Prevention

When it happens

Trigger: Running the migrate-karma-to-vitest migration when a karma.conf.js reporters array contains a non-string element — e.g. nested arrays as produced by karma's multi-reporter form, or objects/functions assigned by reporter plugins.

Common situations: Hand-written karma.conf.js using non-standard reporter values; configs assembled programmatically; Karma plugins that register reporters as objects in the reporters array.

Related errors


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