vitest-dev/vitest · error · TypeError

"snapshotFormat.compareKeys" function is not supported.

Error message

"snapshotFormat.compareKeys" function is not supported.

What it means

Snapshot formatting options are serialised into the resolved config so they can be transferred to worker threads and the snapshot environment. A function value for `snapshotFormat.compareKeys` cannot survive that serialisation, so Vitest rejects it up front (note the TODO in source: a future API may support it via `Function.toString()` or a separate DiffOptions hook).

Solutions

  1. Remove the function form of `compareKeys` from `test.snapshotFormat`.
  2. Use the built-in string-based `compareKeys: null` (default insertion order) or a library-defined token if/when supported.
  3. If custom ordering is essential, file an issue / await the planned DiffOptions API.

Example fix

// before
test: { snapshotFormat: { compareKeys: (a, b) => a < b ? -1 : 1 } }
// after
test: { snapshotFormat: {} }
Defensive patterns

Strategy: type-guard

Validate before calling

if (config.test?.snapshotFormat && typeof config.test.snapshotFormat.compareKeys === 'function') {
  throw new TypeError('snapshotFormat.compareKeys cannot be a function; remove it.')
}

Type guard

function hasFunctionCompareKeys(fmt: any): boolean {
  return fmt != null && typeof fmt.compareKeys === 'function'
}

Prevention

When it happens

Trigger: Passing `test.snapshotFormat = { compareKeys: (a, b) => a.localeCompare(b) }` in a config file.

Common situations: Copy-pasting a jest/pretty-format example that uses a comparator function; trying to enforce custom key ordering in snapshots.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/e87d7e4fb6881ded. Report an issue: GitHub.

Appendix: source

Thrown at packages/vitest/src/node/config/resolveConfig.ts:648

  if (resolved.snapshotEnvironment) {
    resolved.snapshotEnvironment = resolvePath(
      resolved.snapshotEnvironment,
      resolved.root,
    )
  }

  resolved.testNamePattern = resolved.testNamePattern
    ? resolved.testNamePattern instanceof RegExp
      ? resolved.testNamePattern
      : new RegExp(resolved.testNamePattern)
    : undefined

  if (resolved.snapshotFormat && 'plugins' in resolved.snapshotFormat) {
    (resolved.snapshotFormat as any).plugins = []
    // TODO: support it via separate config (like DiffOptions) or via `Function.toString()`
    if (typeof resolved.snapshotFormat.compareKeys === 'function') {
      throw new TypeError(`"snapshotFormat.compareKeys" function is not supported.`)
    }
  }

  const UPDATE_SNAPSHOT = resolved.update || process.env.UPDATE_SNAPSHOT
  resolved.snapshotOptions = {
    expand: resolved.expandSnapshotDiff ?? false,
    snapshotFormat: resolved.snapshotFormat || {},
    updateSnapshot:
      UPDATE_SNAPSHOT === 'all' || UPDATE_SNAPSHOT === 'new' || UPDATE_SNAPSHOT === 'none'
        ? UPDATE_SNAPSHOT
        : isCI && !UPDATE_SNAPSHOT ? 'none' : UPDATE_SNAPSHOT ? 'all' : 'new',
    resolveSnapshotPath: options.resolveSnapshotPath,
    // resolved inside the worker
    snapshotEnvironment: null as any,
  }

  resolved.snapshotSerializers ??= []
  resolved.snapshotSerializers = resolved.snapshotSerializers.map(file =>

View on GitHub (pinned to 1fa9837ec2)