vitest-dev/vitest · error · Error
Cannot take a screenshot in a concurrent test because concur
Error message
Cannot take a screenshot in a concurrent test because concurrent tests run at the same time in the same iframe and affect each other's environment. Use a non-concurrent test to take a screenshot.
What it means
page.screenshot() refuses to run when the active test is marked concurrent (currentTest.concurrent === true). Concurrent browser tests share the same iframe DOM, so a screenshot from one would capture state mutated by sibling tests, producing flaky/misleading images. Defined at packages/browser/src/client/tester/context.ts:318-324.
Source
Thrown at packages/browser/src/client/tester/context.ts:319
if (e.data.event === 'viewport:done' && e.data.iframeId === id) {
channel.removeEventListener('message', handler)
resolve()
}
if (e.data.event === 'viewport:fail' && e.data.iframeId === id) {
channel.removeEventListener('message', handler)
reject(new Error(e.data.error))
}
})
})
},
async screenshot(options = {}) {
const currentTest = getWorkerState().current
if (!currentTest) {
throw new Error('Cannot take a screenshot outside of a test.')
}
if (currentTest.concurrent) {
throw new Error(
'Cannot take a screenshot in a concurrent test because '
+ 'concurrent tests run at the same time in the same iframe and affect each other\'s environment. '
+ 'Use a non-concurrent test to take a screenshot.',
)
}
const repeatCount = currentTest.result?.repeatCount ?? 0
const taskName = getTaskFullName(currentTest)
const number = screenshotIds[repeatCount]?.[taskName] ?? 1
screenshotIds[repeatCount] ??= {}
screenshotIds[repeatCount][taskName] = number + 1
const name
= options.path || `${taskName.replace(/[^a-z0-9]/gi, '-')}-${number}.png`
const [element, ...mask] = await Promise.all([
options.element ? serializeElement(options.element, options) : undefined,View on GitHub (pinned to d568f8ce37)
Solutions
- Remove .concurrent from the test that needs a screenshot, or split the screenshot into a separate non-concurrent test.
- If concurrency is set globally via sequence.concurrent: true, mark the screenshot test with it.sequentialOnly / it.not.concurrent.
- Reorganize: run assertion-heavy tests concurrently and screenshot tests in a sequential describe block.
Example fix
// before
it.concurrent('renders', async () => {
await page.screenshot()
})
// after
it('renders', async () => {
await page.screenshot()
}) Defensive patterns
Strategy: validation
Validate before calling
import { getWorkerState } from 'vitest'
const current = getWorkerState().current
if (current && !current.concurrent) {
await page.screenshot()
} Prevention
- Don't combine .concurrent with screenshots in the same test.
- Use describe.sequential around screenshot tests if global concurrency is enabled.
When it happens
Trigger: Declaring a test with it.concurrent(...) or test.concurrent(...) and then calling page.screenshot() inside its body.
Common situations: Enabling concurrency for speed in browser suites, then adding visual regression screenshots; copying a concurrent test pattern from node tests into browser tests.
Related errors
- Cannot take a screenshot without a test path
- Cannot find iframe with id ${event.iframeId}
- Cannot take a screenshot outside of a test.
- Method "frameLocator" is not supported by the "${provider}"
- Cannot find iframe element. This is a bug in Vitest. Please,
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/f0f19bf4746d388b.json.
Report an issue: GitHub.