vitest-dev/vitest · error · Error
Cannot take a screenshot outside of a test.
Error message
Cannot take a screenshot outside of a test.
What it means
page.screenshot() reads the current test from the worker state; if there is no current test (because screenshot is invoked outside the test function body, e.g. at module top-level, in a beforeEach/beforeAll hook, or after the test has finished), Vitest throws. Screenshots are bound to a task for naming and attachment, so they require an active test context.
Solutions
- Move the page.screenshot() call inside the body of an it/test function.
- If you need a screenshot during setup, capture the DOM state with prettyDOM() instead, or restructure so the screenshot runs inside a test.
- Ensure no setTimeout/setInterval or detached promise triggers the screenshot after the test ends.
Example fix
// before
beforeAll(async () => { await page.screenshot() })
// after
it('renders', async () => { await page.screenshot() }) Defensive patterns
Strategy: validation
Validate before calling
import { getWorkerState } from 'vitest'
if (!getWorkerState().current) {
// skip screenshot — not inside a test
} else {
await page.screenshot()
} Type guard
function insideTest(): boolean {
return !!getWorkerState().current
} Prevention
- Keep page.screenshot() calls inside the body of it/test only.
- Audit helpers that screenshot to ensure they are always called from a test.
- Avoid setTimeout/setInterval callbacks that outlive the test.
When it happens
Trigger: Calling page.screenshot() at the top level of a spec file; calling it inside beforeAll/beforeEach/afterEach/afterAll; calling it after an await that outlives the test (e.g. setTimeout callback); calling it during module import or in a helper invoked outside a test.
Common situations: Taking screenshots for debugging in a setup hook; refactoring that moved the screenshot call out of the test body; race conditions where an async callback fires after the test completed; helper utilities that assume they are always called from a test.
Related errors
- Cannot compare screenshots without a test path
- Cannot take a screenshot in a concurrent test because…
- Cannot take a screenshot without a test path
- Couldn't write file to fs
- No codec found for type
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/c141002116b3d322.
Report an issue: GitHub.
Appendix: source
Thrown at packages/browser/src/client/tester/context.ts:315
iframeId: id,
} satisfies IframeViewportEvent)
return new Promise((resolve, reject) => {
channel.addEventListener('message', function handler(e) {
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 nameView on GitHub (pinned to 1fa9837ec2)