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` at toMatchScreenshot.ts:23-24 when `this.task` or `this.currentTestName` is undefined — i.e. the matcher is invoked outside of an active test scope. The matcher needs the task to record artifacts and the test name to build a stable screenshot filename.
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 d568f8ce37)
Solutions
- Move the `toMatchScreenshot` call inside an `it()`/`test()` body so the matcher state is populated.
- If in a helper, ensure the helper is only called from within a test and that the matcher `this` binding is preserved.
- For setup-time screenshots use Playwright/Vitest browser APIs (`page.screenshot()`) instead of the matcher.
Example fix
// before
beforeAll(async () => {
await page.goto('/')
expect(page).toMatchScreenshot('home.png') // no test context
})
// after
it('renders home', async () => {
await page.goto('/')
expect(page).toMatchScreenshot('home.png')
}) Defensive patterns
Strategy: validation
Validate before calling
function inTestScope(ctx: { task?: unknown; currentTestName?: string }): boolean {
return ctx.task !== undefined && ctx.currentTestName !== undefined
}
if (!inTestScope({ task, currentTestName })) throw new Error('toMatchScreenshot must run inside it()/test()') Prevention
- Call toMatchScreenshot only inside it()/test() bodies.
- Keep matcher helpers on the matcher `this` binding so the test context propagates.
- For setup-time screenshots use page.screenshot() rather than the matcher.
When it happens
Trigger: Calling `toMatchScreenshot` from a plain function, inside `beforeAll`/`setup`, at module top level, or inside a Vitest utility invoked outside a test body. Also happens when the matcher is called inside a worker/preview context that never received the test task from the runner.
Common situations: Trying to take a baseline screenshot during page setup before any `it()` runs. Calling the matcher inside a custom command helper that is also invoked outside tests. Running the matcher via a manual `expect` invocation in a script.
Related errors
- Cannot take a screenshot outside of a test.
- 'toMatchScreenshot' cannot be used with "not"
- Cannot take a screenshot without a test path
- stopChunkTrace cannot be called outside of the test file.
- This command can only be called inside a test file.
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/5e63c7f6985c22a4.json.
Report an issue: GitHub.