vitest-dev/vitest · error · Error

'toMatchScreenshot' cannot be used without test context

Error message

'toMatchScreenshot' cannot be used without test context

What it means

Thrown by `toMatchScreenshot` when the matcher's `this` context lacks `this.task` or `this.currentTestName`. The screenshot command needs the running test's identity (to name reference files, attach artifacts, and compute a per-test counter) and the test path; without them it cannot place the captured image. This typically means the matcher was called outside a live Vitest browser test.

Solutions

  1. Ensure the project uses the browser environment: set `// @vitest-environment browser` at the top of the test file or configure `environment: 'browser'`.
  2. Call `toMatchScreenshot` directly inside an `it(...)`/`test(...)` body, not in `beforeAll` or detached callbacks.
  3. If testing the matcher in isolation, construct a full `MatcherState` with `task`, `currentTestName`, and `testPath`, or refactor to invoke it through the real runner.

Example fix

// before (called outside a test, e.g. in a helper module)
expect(page).toMatchScreenshot('home')

// after
import { test, expect } from 'vitest'
test('home renders', () => {
  expect(page).toMatchScreenshot('home')
})
Defensive patterns

Strategy: validation

Validate before calling

// ensure the matcher runs inside a live browser test
import { test, expect } from 'vitest'
test('visual', () => {
  expect(page).toMatchScreenshot('home')
})

Prevention

When it happens

Trigger: Calling `toMatchScreenshot` from a plain script, a Vitest `beforeAll`/global setup that runs outside the test scope, a manually constructed expect context, or any environment where the matcher is invoked without Vitest binding its `MatcherState`.

Common situations: Unit-testing the matcher itself in isolation; importing the browser tester entry in Node; calling the matcher inside a `setTimeout`/detached promise after the test finished; running browser matchers under the default Node environment instead of `@vitest/browser`.

Related errors


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

Appendix: source

Thrown at packages/browser/src/client/tester/expect/toMatchScreenshot.ts:24

import { getBrowserState } from '../../utils'
import { serializeElement } from '../tester-utils'

const counters = new Map<string, { current: number }>([])

export default async function toMatchScreenshot(
  this: MatcherState,
  actual: BrowserPage | Element | Locator,
  nameOrOptions?: ScreenshotMatcherOptions | string,
  options: ScreenshotMatcherOptions = typeof nameOrOptions === 'object'
    ? nameOrOptions
    : {},
): AsyncMatcherResult {
  if (this.isNot) {
    throw new Error('\'toMatchScreenshot\' cannot be used with "not"')
  }

  if (this.task === undefined || this.currentTestName === undefined) {
    throw new Error('\'toMatchScreenshot\' cannot be used without test context')
  }

  const counterName = `${this.task.result?.repeatCount ?? 0}${this.testPath}${this.currentTestName}`
  let counter = counters.get(counterName)

  if (counter === undefined) {
    counter = { current: 0 }

    counters.set(counterName, counter)
  }

  counter.current += 1

  const name = typeof nameOrOptions === 'string'
    ? nameOrOptions
    : `${this.currentTestName} ${counter.current}`

  const isPageTarget = isBrowserPage(actual)

View on GitHub (pinned to 1fa9837ec2)