jestjs/jest · error · TypeError

The option summaryThreshold should be a number

Error message

The option summaryThreshold should be a number

What it means

Thrown as a TypeError by SummaryReporter's _validateOptions when options.summaryThreshold is truthy but typeof !== 'number'. summaryThreshold controls how many test suites must run before the failing-test summary is re-printed at the end (default 20 per the constructor). Validation runs in the constructor, so the error surfaces at reporter instantiation — typically at jest startup.

Source

Thrown at packages/jest-reporters/src/SummaryReporter.ts:78

  static readonly filename = __filename;

  constructor(
    globalConfig: Config.GlobalConfig,
    options?: SummaryReporterOptions,
  ) {
    super();
    this._globalConfig = globalConfig;
    this._estimatedTime = 0;
    this._validateOptions(options);
    this._summaryThreshold = options?.summaryThreshold ?? 20;
  }

  private _validateOptions(options?: SummaryReporterOptions) {
    if (
      options?.summaryThreshold &&
      typeof options.summaryThreshold !== 'number'
    ) {
      throw new TypeError('The option summaryThreshold should be a number');
    }
  }

  // If we write more than one character at a time it is possible that
  // Node.js exits in the middle of printing the result. This was first observed
  // in Node.js 0.10 and still persists in Node.js 6.7+.
  // Let's print the test failure summary character by character which is safer
  // when hundreds of tests are failing.
  private _write(string: string) {
    for (let i = 0; i < string.length; i++) {
      process.stderr.write(string.charAt(i));
    }
  }

  override onRunStart(
    aggregatedResults: AggregatedResult,
    options: ReporterOnStartOptions,
  ): void {

View on GitHub (pinned to f49721c78e)

Solutions

  1. Pass a plain number literal: {summaryThreshold: 50}.
  2. When sourcing from env, convert: {summaryThreshold: Number(process.env.SUMMARY_THRESHOLD) || 20}.
  3. Validate config in a setup script or use a typed config (jest.config.ts) so the editor flags non-numeric values.

Example fix

// before
reporters: [['jest-summary-reporter', { summaryThreshold: '50' }]]
// after
reporters: [['jest-summary-reporter', { summaryThreshold: 50 }]]
Defensive patterns

Strategy: validation

Validate before calling

function resolveSummaryThreshold(raw: unknown): number {
  if (raw == null) return 20;
  if (typeof raw !== 'number' || !Number.isFinite(raw)) {
    throw new TypeError('summaryThreshold must be a finite number');
  }
  return raw;
}
const summaryThreshold = resolveSummaryThreshold(process.env.SUMMARY_THRESHOLD ?? 20);
reporters: [['<rootDir>/summary-reporter.js', { summaryThreshold }]];

Type guard

const isSummaryThreshold = (v: unknown): v is number =>
  typeof v === 'number' && Number.isFinite(v);

const opts = isSummaryThreshold(rawThreshold)
  ? { summaryThreshold: rawThreshold }
  : { summaryThreshold: 20 };

Prevention

When it happens

Trigger: Configuring SummaryReporter with a non-numeric threshold: ['default', ['jest-summary-reporter', {summaryThreshold: '20'}]]; passing a string from an env var without conversion: {summaryThreshold: process.env.SUMMARY_THRESHOLD}; an array or object passed by mistake.

Common situations: Reading the threshold from an env var (always a string) without Number(); a config file in JSON/JSONC that quotes the number; copy-paste from documentation that quoted the value.

Related errors


AI-assisted analysis of jestjs/jest@f49721c78e (2026-08-03). Data as JSON: /data/errors/73306fd1e60bb1a8.json. Report an issue: GitHub.