vitest-dev/vitest · error · Error

`resolveOptions` has to be used in a test file

Error message

`resolveOptions` has to be used in a test file

What it means

`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).

Source

Thrown at packages/browser/src/node/commands/screenshotMatcher/utils.ts:102

    }
  }
}

export function resolveOptions(
  {
    context,
    name,
    options,
    testName,
  }: {
    context: BrowserCommandContext
    name: string
    testName: string
    options: ScreenshotMatcherOptions
  },
): ResolvedOptions {
  if (context.testPath === undefined) {
    throw new Error('`resolveOptions` has to be used in a test file')
  }

  const resolvedOptions = deepMerge<GlobalOptions>(
    Object.create(null),
    defaultOptions,
    context.project.config.browser.expect?.toMatchScreenshot ?? {},
    options,
  )

  const extensionFromName = extname(name)

  // technically the type is a lie, but we check beneath and reassign otherwise
  let extension = extensionFromName.replace(/^\./, '') as SupportedCodecs

  // when `type` will be supported in `screenshotOptions`:
  // - `'png'` should end up in `defaultOptions.screenshotOptions.type`
  // - this condition should be switched around
  // - the assignment should be `resolvedOptions.screenshotOptions.type = extension`

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Only call `resolveOptions` (and `screenshotMatcher`) from within a running browser test where `context.testPath` is set.
  2. When unit-testing this helper, pass a stub context with `testPath: resolve('/path/to/fake.test.ts')`.
  3. Avoid calling screenshot APIs from global setup hooks that lack a bound test file.

Example fix

// before
resolveOptions({ context: {}, name: 'a.png', testName: 'x', options: {} })

// after
resolveOptions({
  context: { testPath: '/abs/test/basic.test.ts', project, ...rest },
  name: 'a.png',
  testName: 'x',
  options: {},
})
Defensive patterns

Strategy: validation

Validate before calling

function canResolveOptions(ctx: { testPath?: unknown }): boolean {
  return typeof ctx.testPath === 'string' && ctx.testPath.length > 0
}

Type guard

const isTestFileContext = (c: { testPath?: unknown }): c is { testPath: string } =>
  typeof c.testPath === 'string'

Prevention

When it happens

Trigger: Directly importing and calling `resolveOptions({ context, name, testName, options })` (or `screenshotMatcher`, which calls it) with a `BrowserCommandContext` whose `testPath === undefined`.

Common situations: 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.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/b9216eb152ba115d.json. Report an issue: GitHub.