{"id":"2fec3b4ccbe5cee8","repo":"vitest-dev/vitest","slug":"cannot-take-a-screenshot-without-a-test-path","errorCode":null,"errorMessage":"Cannot take a screenshot without a test path","messagePattern":"Cannot take a screenshot without a test path","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser-playwright/src/commands/screenshot.ts","lineNumber":38,"sourceCode":"    transform: none !important;\n  }\n`\n\n/**\n * Takes a screenshot using the provided browser context and returns a buffer and the expected screenshot path.\n *\n * **Note**: the returned `path` indicates where the screenshot *might* be found.\n * It is not guaranteed to exist, especially if `options.save` is `false`.\n *\n * @throws {Error} If the function is not called within a test or if the browser provider does not support screenshots.\n */\nexport async function takeScreenshot(\n  context: BrowserCommandContext,\n  name: string,\n  options: Omit<ScreenshotCommandOptions, 'base64'>,\n): Promise<{ buffer: Buffer<ArrayBufferLike>; path: string }> {\n  if (!context.testPath) {\n    throw new Error(`Cannot take a screenshot without a test path`)\n  }\n\n  const path = resolveScreenshotPath(\n    context.testPath,\n    name,\n    context.project.config,\n    options.path,\n  )\n\n  // playwright does not need a screenshot path if we don't intend to save it\n  let savePath: string | undefined\n\n  if (options.save) {\n    savePath = normalize(path)\n\n    assertBrowserApiWrite(context.project, savePath)\n    assertBrowserFileAccess(context.project, savePath)\n","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/browser-playwright/src/commands/screenshot.ts#L20-L56","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (setup.ts, imported globally)\nimport { page } from '@vitest/browser'\nawait page.screenshot() // no test context -> throws\n\n// after (inside a test file)\nimport { test } from 'vitest'\nimport { page } from '@vitest/browser'\ntest('visual', async () => {\n  await page.screenshot()\n})","handlingStrategy":"validation","validationCode":"if (!context.testPath) {\n  throw new Error('page.screenshot() must be called from within a test')\n}\nawait takeScreenshot(context, name, options)","typeGuard":"function hasTestPath(c: BrowserCommandContext): c is BrowserCommandContext & { testPath: string } {\n  return typeof c.testPath === 'string' && c.testPath.length > 0\n}","tryCatchPattern":"try {\n  await takeScreenshot(ctx, name, opts)\n} catch (err) {\n  if (err instanceof Error && /without a test path/.test(err.message)) {\n    // not in a test: skip or route to a direct playwright screenshot\n  } else throw err\n}","preventionTips":["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."],"tags":["browser","screenshot","playwright","test-context","vitest"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}