vitest-dev/vitest · error · Error

invalid snapshot serializer file

Error message

invalid snapshot serializer file ${file}. Must export a default object

What it means

Thrown by loadSnapshotSerializers when a file listed in `config.snapshotSerializers` is imported but its default export is missing or not a non-null object. Snapshot serializers must be objects conforming to Jest's serializer contract; the first check ensures the shape is an object before validating its methods.

Solutions

  1. Default-export a serializer object: `export default { test: v => typeof v === 'string', serialize: (v, ...rest) => ... , print: undefined }`.
  2. If the serializer is a named export, re-export as default: `export { mySerializer as default }`.
  3. Confirm every entry in `snapshotSerializers` points to a real serializer file.
  4. Remove the entry if a serializer is no longer needed.

Example fix

// before — my-serializer.ts
export const mySerializer = { test() {}, serialize() {} }

// after
export default { test() {}, serialize() {} }
Defensive patterns

Strategy: type-guard

Validate before calling

async function loadSerializer(path: string) {
  const mod = await import(/* @vite-ignore */ path)
  if (!mod?.default || typeof mod.default !== 'object') {
    throw new TypeError(`${path} must default-export a serializer object`)
  }
  return mod.default
}

Type guard

function isSerializerObject(v: unknown): v is object {
  return typeof v === 'object' && v !== null
}

Prevention

When it happens

Trigger: Adding a path to `snapshotSerializers: ['./my-serializer.js']` where the file has no default export, exports null/undefined/primitive as default, or uses a named export.

Common situations: Porting a Jest serializer that used a named export; forgetting `export default`; pointing the array at a non-serializer module by mistake.

Related errors


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

Appendix: source

Thrown at packages/vitest/src/runtime/setup-common.ts:74

  }
  else {
    throw new Error(
      `invalid diff config file ${config.diff}. Must have a default export with config object`,
    )
  }
}

export async function loadSnapshotSerializers(
  config: SerializedConfig,
  moduleRunner: PublicModuleRunner,
): Promise<void> {
  const files = config.snapshotSerializers

  const snapshotSerializers = await Promise.all(
    files.map(async (file) => {
      const mo = await moduleRunner.import(file)
      if (!mo || typeof mo.default !== 'object' || mo.default === null) {
        throw new Error(
          `invalid snapshot serializer file ${file}. Must export a default object`,
        )
      }

      const config = mo.default
      if (
        typeof config.test !== 'function'
        || (typeof config.serialize !== 'function'
          && typeof config.print !== 'function')
      ) {
        throw new TypeError(
          `invalid snapshot serializer in ${file}. Must have a 'test' method along with either a 'serialize' or 'print' method.`,
        )
      }

      return config as SnapshotSerializer
    }),
  )

View on GitHub (pinned to 1fa9837ec2)