vitest-dev/vitest · error · TypeError

.toMatch() expects to receive a string, but got

Error message

.toMatch() expects to receive a string, but got ${typeof actual}

What it means

The toMatch matcher requires the actual value (this._obj) to be a string; it then does either includes (for a string expected) or match (for a RegExp expected). A non-string actual throws a TypeError before any matching.

Solutions

  1. Ensure actual is a string: extract the right field (e.g. res.body.message) or coerce with String(actual).
  2. Use the correct matcher for non-strings (toBe, toEqual, toBeCloseTo, toContain).
  3. Add a typeof guard or non-null check before the assertion.

Example fix

// before
expect(statusCode).toMatch(200)
// after
expect(String(statusCode)).toMatch(/^2\d\d$/)
// or, more idiomatic
expect(statusCode).toBe(200)
Defensive patterns

Strategy: type-guard

Validate before calling

function assertStringForMatch(actual) {
  if (typeof actual !== 'string') {
    throw new TypeError(`.toMatch() requires a string, got ${typeof actual}`)
  }
}

Type guard

function isString(v): v is string {
  return typeof v === 'string'
}

Prevention

When it happens

Trigger: expect(actual).toMatch(expected) where actual is a number, object, array, null, undefined, etc.

Common situations: Calling toMatch on a number expecting it to match a numeric pattern (use toBeCloseTo / type coercion); calling toMatch on a parsed JSON object instead of a string field; calling on undefined from a missing property.

Related errors


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

Appendix: source

Thrown at packages/expect/src/jest-expect.ts:227

        false,
      ])
      const message
        = stripped === 0
          ? msg
          : `${msg}\n(${stripped} matching ${
            stripped === 1 ? 'property' : 'properties'
          } omitted from actual)`
      throw new AssertionError(message, {
        showDiff: true,
        expected,
        actual: actualSubset,
      })
    }
  })
  def('toMatch', function (expected: string | RegExp) {
    const actual = this._obj as string
    if (typeof actual !== 'string') {
      throw new TypeError(
        `.toMatch() expects to receive a string, but got ${typeof actual}`,
      )
    }

    return this.assert(
      typeof expected === 'string'
        ? actual.includes(expected)
        : actual.match(expected),
      `expected #{this} to match #{exp}`,
      `expected #{this} not to match #{exp}`,
      expected,
      actual,
    )
  })
  def('toContain', function (item) {
    const actual = this._obj as
      | Iterable<unknown>
      | string

View on GitHub (pinned to 1fa9837ec2)