vitest-dev/vitest · error · AssertionError

${formatCalls(spy, msg, args)}

Error message

${formatCalls(spy, msg, args)}

What it means

AssertionError thrown by toHaveBeenCalledWith/toBeCalledWith when the spy was never called with the exact arguments (positive form) or was called with them under .not. The message is enriched by formatCalls, which lists every received call with a diff against the expected arguments.

Source

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

      jestEquals(aItem, b[i], [...customTesters, iterableEquality]),
    )
  }

  def(['toHaveBeenCalledWith', 'toBeCalledWith'], function (...args) {
    const spy = getSpy(this)
    const spyName = spy.getMockName()
    const pass = spy.mock.calls.some(callArg => equalsArgumentArray(callArg, args))
    const isNot = utils.flag(this, 'negate') as boolean

    const msg = utils.getMessage(this, [
      pass,
      `expected "${spyName}" to be called with arguments: #{exp}`,
      `expected "${spyName}" to not be called with arguments: #{exp}`,
      args,
    ])

    if ((pass && isNot) || (!pass && !isNot)) {
      throw new AssertionError(formatCalls(spy, msg, args))
    }
  })
  def('toHaveBeenCalledExactlyOnceWith', function (...args) {
    const spy = getSpy(this)
    const spyName = spy.getMockName()
    const callCount = spy.mock.calls.length
    const hasCallWithArgs = spy.mock.calls.some(callArg => equalsArgumentArray(callArg, args))
    const pass = hasCallWithArgs && callCount === 1
    const isNot = utils.flag(this, 'negate') as boolean

    const msg = utils.getMessage(this, [
      pass,
      `expected "${spyName}" to be called once with arguments: #{exp}`,
      `expected "${spyName}" to not be called once with arguments: #{exp}`,
      args,
    ])

    if ((pass && isNot) || (!pass && !isNot)) {

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Read the per-call diff in the failure output to find which argument differs.
  2. If only a subset of arguments matters, wrap expected args with asymmetric matchers (expect.objectContaining, expect.any).
  3. Confirm the spy captured the call you think it did — check spy.mock.calls in a debug step.

Example fix

// before
expect(log).toHaveBeenCalledWith('user', 42);
// after (relax shape)
expect(log).toHaveBeenCalledWith('user', expect.any(Number));
Defensive patterns

Strategy: validation

Validate before calling

const recorded = spy.mock.calls;
if (!recorded.some(c => c.length === args.length && c.every((v, i) => jestEquals(v, args[i])))) {
  console.warn('no call matches expected args; recorded:', recorded);
}

Prevention

When it happens

Trigger: expect(spy).toHaveBeenCalledWith(arg1, arg2) where no recorded call deep-equals (arg1, arg2); or the negated form where at least one call did match. Uses equalsArgumentArray (jestEquals element-by-element with iterableEquality).

Common situations: Argument shape mismatch — e.g. the code passed an object with extra keys, a string instead of a number, or a different array length. The diff in the message highlights the first divergence per call.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/7e29d9b6c6168bb6.json. Report an issue: GitHub.