{"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/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/browser/src/node/commands/screenshotMatcher/utils.ts#L84-L120","documentation":"`resolveOptions` builds screenshot/diff paths relative to `context.testPath`. Without a test file path it cannot compute the reference directory, so it rejects the call rather than guessing. This is the underlying guard called by `screenshotMatcher` (see error 60).","triggerScenarios":"Directly importing and calling `resolveOptions({ context, name, testName, options })` (or `screenshotMatcher`, which calls it) with a `BrowserCommandContext` whose `testPath === undefined`.","commonSituations":"Calling `resolveOptions` directly from a custom plugin or command outside a real test; unit-testing `resolveOptions` with a stubbed context that omits `testPath`; using `toMatchScreenshot` from a setup file that runs before the test file is known.","solutions":["Only call `resolveOptions` (and `screenshotMatcher`) from within a running browser test where `context.testPath` is set.","When unit-testing this helper, pass a stub context with `testPath: resolve('/path/to/fake.test.ts')`.","Avoid calling screenshot APIs from global setup hooks that lack a bound test file."],"exampleFix":"// before\nresolveOptions({ context: {}, name: 'a.png', testName: 'x', options: {} })\n\n// after\nresolveOptions({\n  context: { testPath: '/abs/test/basic.test.ts', project, ...rest },\n  name: 'a.png',\n  testName: 'x',\n  options: {},\n})","handlingStrategy":"validation","validationCode":"function canResolveOptions(ctx: { testPath?: unknown }): boolean {\n  return typeof ctx.testPath === 'string' && ctx.testPath.length > 0\n}","typeGuard":"const isTestFileContext = (c: { testPath?: unknown }): c is { testPath: string } =>\n  typeof c.testPath === 'string'","tryCatchPattern":null,"preventionTips":["Only call resolveOptions (and screenshotMatcher) from a real running browser test.","When unit-testing resolveOptions, pass a stub context with a concrete testPath.","Don't import screenshot utilities from setup files lacking a bound test file."],"tags":["screenshot","browser-command","validation","configuration"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}