{"id":"7956e77a5d9c29c9","repo":"vitest-dev/vitest","slug":"cannot-compare-screenshots-without-a-test-path","errorCode":null,"errorMessage":"Cannot compare screenshots without a test path","messagePattern":"Cannot compare screenshots without a test path","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser/src/node/commands/screenshotMatcher/index.ts","lineNumber":84,"sourceCode":"/**\n * Browser command that compares a screenshot against a stored reference.\n *\n * The comparison workflow is organized as follows:\n *\n * 1. Load existing reference (if any)\n * 2. Capture a stable screenshot (retrying until the page stops changing)\n * 3. Determine the outcome based on capture results and update settings\n * 4. Write any necessary files (new references, diffs)\n * 5. Return result for the test runner\n */\nexport const screenshotMatcher: BrowserCommand<ScreenshotMatcherArguments> = async (\n  context,\n  name,\n  testName,\n  options,\n): ScreenshotMatcherOutput => {\n  if (!context.testPath) {\n    throw new Error('Cannot compare screenshots without a test path')\n  }\n\n  const { element, target } = options\n  const {\n    codec,\n    comparator,\n    paths,\n    resolvedOptions: { comparatorName, comparatorOptions, screenshotOptions, timeout },\n  } = resolveOptions({ context, name, testName, options })\n\n  const screenshotName = `${Date.now()}-${basename(paths.reference)}`\n  const screenshotCaptureOptions = {\n    context,\n    element,\n    name: screenshotName,\n    screenshotOptions,\n    target,\n  } satisfies Parameters<typeof takeScreenshotBuffer>[0]","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/browser/src/node/commands/screenshotMatcher/index.ts#L66-L102","documentation":"The `screenshotMatcher` browser command requires `context.testPath` to resolve where reference/diff images are written relative to the test file. If the command is invoked with a context whose `testPath` is falsy, screenshot paths cannot be computed and the command refuses to run rather than writing files to an arbitrary location.","triggerScenarios":"Calling `expect(...).toMatchScreenshot()` (which routes to `screenshotMatcher`) from a context where `BrowserCommandContext.testPath` is undefined — e.g. invoking the command outside a registered Vitest test, from a custom runner that doesn't populate `testPath`, or before the test task is bound to the command context.","commonSituations":"Custom test runners or plugins that call `project.browser.triggerCommand('screenshotMatcher', ...)` directly without forwarding `testPath`; running the screenshot assertion from setup/teardown hooks in some configurations; bugs in third-party frameworks that wrap Vitest's browser command API.","solutions":["Run `toMatchScreenshot()` only inside an actual `it`/`test` block running under the Vitest browser runner, not from a plain script or outside a test task.","If invoking `triggerCommand` manually, construct the `BrowserCommandContext` with a valid `testPath` pointing at the test file.","Update Vitest and `@vitest/browser` to the same version; mismatches can cause the context to be missing fields like `testPath`."],"exampleFix":"// before\nawait page.screenshotMatcher()\n\n// after — inside a Vitest browser test\nimport { test, expect } from 'vitest/browser'\ntest('visual', async ({ page }) => {\n  await expect(page.getByRole('main')).toMatchScreenshot()\n})","handlingStrategy":"validation","validationCode":"import type { BrowserCommandContext } from 'vitest/node'\n\nfunction assertScreenshotContext(ctx: BrowserCommandContext): void {\n  if (!ctx.testPath) {\n    throw new Error('toMatchScreenshot must run inside a browser test; context.testPath is missing')\n  }\n}\n// call before invoking screenshotMatcher:\nassertScreenshotContext(context)","typeGuard":"const hasTestPath = (c: BrowserCommandContext): c is BrowserCommandContext & { testPath: string } =>\n  typeof c.testPath === 'string' && c.testPath.length > 0","tryCatchPattern":null,"preventionTips":["Only call toMatchScreenshot() inside `it`/`test` blocks of a browser test.","Don't invoke project.browser.triggerCommand('screenshotMatcher', ...) from setup hooks or plain scripts.","Keep Vitest and @vitest/browser on the same version."],"tags":["browser","screenshot","browser-command","validation"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}