vitest-dev/vitest · error · Error

Precision is not a Number

Error message

Precision is not a Number

What it means

CloseTo's second argument (precision, default 2) must also be a Number; isA('Number', precision) guards it independently of the sample. A non-numeric precision throws even when the sample is valid.

Solutions

  1. Pass an integer number for precision: expect.closeTo(1.5, 2).
  2. Coerce with Number(...) and Math.round for config-sourced precision.
  3. Omit precision to accept the default of 2.

Example fix

// before
expect(value).toEqual(expect.closeTo(1.5, '2'))
// after
expect(value).toEqual(expect.closeTo(1.5, 2))
Defensive patterns

Strategy: type-guard

Validate before calling

function asCloseTo(sample, precision = 2) {
  if (typeof precision !== 'number' || Number.isNaN(precision)) {
    throw new TypeError('expect.closeTo precision must be a Number')
  }
  return expect.closeTo(sample, precision)
}

Type guard

function isIntegerNumber(v): v is number {
  return typeof v === 'number' && Number.isInteger(v)
}

Prevention

When it happens

Trigger: expect.closeTo(sample, precision) where precision is a string, null, object, or NaN (e.g. expect.closeTo(1.5, '2')).

Common situations: Passing precision read from a config/env as a string; passing undefined explicitly (default applies, so usually fine); passing a float precision where an integer was expected.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/e6248eef8af86515. Report an issue: GitHub.

Appendix: source

Thrown at packages/expect/src/jest-asymmetric-matchers.ts:350

  toString() {
    return `String${this.inverse ? 'Not' : ''}Matching`
  }

  getExpectedType() {
    return 'string'
  }
}

class CloseTo extends AsymmetricMatcher<number> {
  private readonly precision: number

  constructor(sample: number, precision = 2, inverse = false) {
    if (!isA('Number', sample)) {
      throw new Error('Expected is not a Number')
    }

    if (!isA('Number', precision)) {
      throw new Error('Precision is not a Number')
    }

    super(sample)
    this.inverse = inverse
    this.precision = precision
  }

  asymmetricMatch(other: number) {
    if (!isA('Number', other)) {
      return false
    }

    let result = false
    if (
      other === Number.POSITIVE_INFINITY
      && this.sample === Number.POSITIVE_INFINITY
    ) {
      result = true // Infinity - Infinity is NaN

View on GitHub (pinned to 1fa9837ec2)