vitest-dev/vitest · error · TestSyntaxError

' ' cannot be used with 'test.fails

Error message

'${getAssertionName(obj)}' cannot be used with 'test.fails'

What it means

Thrown by `getTest` as a `TestSyntaxError` when the active test was declared with `test.fails(...)` (or `it.fails`) and a snapshot assertion is used. `test.fails` inverts pass/fail semantics, which is incompatible with snapshot matching (a 'failing' snapshot would corrupt the stored snapshot), so Vitest disallows the combination. The message names the offending assertion.

Solutions

  1. Remove the snapshot assertion from the `test.fails` body — use a non-snapshot expectation for the negative case.
  2. If you want to snapshot, drop the `.fails` modifier and assert the expected failure explicitly (e.g. `expect(...).toThrow()`).
  3. Split into two tests: one `.fails` for the error case and a normal test for the snapshot.

Example fix

// before
test.fails('renders', () => {
  expect(render()).toMatchSnapshot()
})

// after
test('renders', () => {
  expect(render()).toMatchSnapshot()
})
Defensive patterns

Strategy: validation

Validate before calling

// do not combine test.fails with snapshot assertions
if (testContext.fails) throw new Error('move snapshot out of test.fails')

Prevention

When it happens

Trigger: Writing `test.fails('x', () => { expect(value).toMatchSnapshot() })` or `it.fails(...)` with any snapshot assertion inside; nesting a snapshot assertion inside a test marked `.fails`.

Common situations: Using `test.fails` as a quick way to assert that something is 'wrong' and adding a snapshot in the same body; converting an existing failing test to `test.fails` without removing snapshot assertions.

Related errors


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

Appendix: source

Thrown at packages/vitest/src/integrations/snapshot/chai.ts:71

    testId: test.id,
  }
}

function getAssertionName(assertion: Chai.Assertion): string {
  const name = chai.util.flag(assertion, '_name') as string | undefined
  if (!name) {
    throw new Error('Assertion name is not set. This is a bug in Vitest. Please, open a new issue with reproduction.')
  }
  return name
}

function getTest(obj: Chai.Assertion) {
  const test = chai.util.flag(obj, 'vitest-test') as Test | undefined
  if (!test) {
    throw new Error(`'${getAssertionName(obj)}' cannot be used without test context`)
  }
  if (test.fails) {
    throw new TestSyntaxError(`'${getAssertionName(obj)}' cannot be used with 'test.fails'`)
  }
  return test
}

function validateAssertion(assertion: Chai.Assertion): void {
  if (chai.util.flag(assertion, 'negate')) {
    throw new Error(`${getAssertionName(assertion)} cannot be used with "not"`)
  }
}

export const SnapshotPlugin: ChaiPlugin = (chai, utils) => {
  for (const key of ['matchSnapshot', 'toMatchSnapshot']) {
    utils.addMethod(
      chai.Assertion.prototype,
      key,
      wrapAssertion(utils, key, function (
        this,
        propertiesOrHint?: object | string,

View on GitHub (pinned to 1fa9837ec2)