{"record":{"id":"b9216eb152ba115d","repo":"vitest-dev/vitest","slug":"resolveoptions-has-to-be-used-in-a-test-file","errorCode":null,"errorMessage":"`resolveOptions` has to be used in a test file","messagePattern":"`resolveOptions` has to be used in a test file","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser/src/node/commands/screenshotMatcher/utils.ts","lineNumber":102,"sourceCode":"    }\n  }\n}\n\nexport function resolveOptions(\n  {\n    context,\n    name,\n    options,\n    testName,\n  }: {\n    context: BrowserCommandContext\n    name: string\n    testName: string\n    options: ScreenshotMatcherOptions\n  },\n): ResolvedOptions {\n  if (context.testPath === undefined) {\n    throw new Error('`resolveOptions` has to be used in a test file')\n  }\n\n  const resolvedOptions = deepMerge<GlobalOptions>(\n    Object.create(null),\n    defaultOptions,\n    context.project.config.browser.expect?.toMatchScreenshot ?? {},\n    options,\n  )\n\n  const extensionFromName = extname(name)\n\n  // technically the type is a lie, but we check beneath and reassign otherwise\n  let extension = extensionFromName.replace(/^\\./, '') as SupportedCodecs\n\n  // when `type` will be supported in `screenshotOptions`:\n  // - `'png'` should end up in `defaultOptions.screenshotOptions.type`\n  // - this condition should be switched around\n  // - the assignment should be `resolvedOptions.screenshotOptions.type = extension`","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/browser/src/node/commands/screenshotMatcher/utils.ts#L84-L120","documentation":"resolveOptions in screenshotMatcher/utils.ts reads project-level defaults and merges them with per-call options, but it can only do that when it knows which test file is running. It throws when context.testPath is undefined, i.e. when the screenshot matcher resolution logic is invoked outside a test-file execution context where the testPath has not been threaded through.","triggerScenarios":"Calling resolveOptions (directly or via a screenshot-matcher command) from a setup file, a global setup hook, or a custom command registered without a BrowserCommandContext that carries testPath. Also reproducible if the command is triggered from a session that is not tied to a specific test file.","commonSituations":"Using toMatchScreenshot inside beforeEach/beforeAll at the top level of a non-test module; invoking the screenshot matcher from a manual RPC call in a custom integration; a plugin that re-enters the matcher before the runner has assigned a testPath.","solutions":["Move the screenshot-matcher call inside an actual `it`/`test` body so the runner populates testPath on the command context.","If invoking the command programmatically, construct the BrowserCommandContext with a valid testPath referring to an existing test file.","Avoid calling screenshot-matcher utilities from setup files or hooks that run before a test file context exists."],"exampleFix":"// before - called from a setup file, no test context\nresolveOptions({ context, name, options, testName })\n// after - only call inside a test\nimport { test } from 'vitest'\ntest('visual', async () => {\n  await expect(page).toMatchScreenshot('home.png')\n})","handlingStrategy":"validation","validationCode":"function hasTestPath(ctx: { testPath?: string }): ctx is { testPath: string } {\n  return typeof ctx.testPath === 'string' && ctx.testPath.length > 0\n}","typeGuard":"function isTestFileContext(ctx: unknown): ctx is { testPath: string } {\n  return !!ctx && typeof ctx === 'object' && typeof (ctx as any).testPath === 'string'\n}","tryCatchPattern":null,"preventionTips":["Only call screenshot-matcher utilities from inside an `it`/`test` body.","When constructing a BrowserCommandContext programmatically, always pass a testPath.","Do not invoke matcher commands from setup files that run outside a test file scope."],"tags":["screenshot","browser-command","test-context","config"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}