vitest-dev/vitest · error · Error
Cannot take a screenshot without a test path
Error message
Cannot take a screenshot without a test path
What it means
Thrown by the Playwright screenshot browser command (vitest/browser page.screenshot / expect screenshot internals) when context.testPath is missing. Vitest derives the screenshot output path from the running test's file, so a screenshot must be taken synchronously inside a test/task that has a registered test path.
Source
Thrown at packages/browser-playwright/src/commands/screenshot.ts:38
transform: none !important;
}
`
/**
* Takes a screenshot using the provided browser context and returns a buffer and the expected screenshot path.
*
* **Note**: the returned `path` indicates where the screenshot *might* be found.
* It is not guaranteed to exist, especially if `options.save` is `false`.
*
* @throws {Error} If the function is not called within a test or if the browser provider does not support screenshots.
*/
export async function takeScreenshot(
context: BrowserCommandContext,
name: string,
options: Omit<ScreenshotCommandOptions, 'base64'>,
): Promise<{ buffer: Buffer<ArrayBufferLike>; path: string }> {
if (!context.testPath) {
throw new Error(`Cannot take a screenshot without a test path`)
}
const path = resolveScreenshotPath(
context.testPath,
name,
context.project.config,
options.path,
)
// playwright does not need a screenshot path if we don't intend to save it
let savePath: string | undefined
if (options.save) {
savePath = normalize(path)
assertBrowserApiWrite(context.project, savePath)
assertBrowserFileAccess(context.project, savePath)
View on GitHub (pinned to d568f8ce37)
Solutions
- Move the screenshot call inside an it/test block so Vitest attaches a testPath.
- If using a custom browser command, only invoke it from within a running test.
- For setup-time captures, use Playwright's page.screenshot directly with an explicit path instead of Vitest's screenshot API.
Example fix
// before (setup.ts, imported globally)
import { page } from '@vitest/browser'
await page.screenshot() // no test context -> throws
// after (inside a test file)
import { test } from 'vitest'
import { page } from '@vitest/browser'
test('visual', async () => {
await page.screenshot()
}) Defensive patterns
Strategy: validation
Validate before calling
if (!context.testPath) {
throw new Error('page.screenshot() must be called from within a test')
}
await takeScreenshot(context, name, options) Type guard
function hasTestPath(c: BrowserCommandContext): c is BrowserCommandContext & { testPath: string } {
return typeof c.testPath === 'string' && c.testPath.length > 0
} Try / catch
try {
await takeScreenshot(ctx, name, opts)
} catch (err) {
if (err instanceof Error && /without a test path/.test(err.message)) {
// not in a test: skip or route to a direct playwright screenshot
} else throw err
} Prevention
- Only call screenshot APIs from inside it/test bodies.
- Keep shared page helpers free of @vitest/browser screenshot calls.
- For setup-time captures, use Playwright's page.screenshot with an explicit absolute path.
When it happens
Trigger: Calling the screenshot API from global setup, a beforeAll/beforeEach in a non-test module, a worker thread, or any context where Vitest has not associated the call with a test file. Also triggered by invoking the command manually with a synthesized BrowserCommandContext lacking testPath.
Common situations: Taking screenshots in setup files or shared utils imported outside tests, running screenshot logic in onConsoleLog/onTask hooks, or calling page.screenshot inside a custom command registered outside the test lifecycle.
Related errors
- stopChunkTrace cannot be called outside of the test file.
- This command can only be called inside a test file.
- Cannot upload files outside of a test
- Element not found: ${v.element}
- The ${provider.name} provider does not support tracing.
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/2fec3b4ccbe5cee8.json.
Report an issue: GitHub.