{"record":{"id":"a48571de734c3f65","repo":"vitest-dev/vitest","slug":"invalid-snapshot-serializer-file-file-must-exp","errorCode":null,"errorMessage":"invalid snapshot serializer file ${file}. Must export a default object","messagePattern":"invalid snapshot serializer file (.+?)\\. Must export a default object","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/runtime/setup-common.ts","lineNumber":74,"sourceCode":"  }\n  else {\n    throw new Error(\n      `invalid diff config file ${config.diff}. Must have a default export with config object`,\n    )\n  }\n}\n\nexport async function loadSnapshotSerializers(\n  config: SerializedConfig,\n  moduleRunner: PublicModuleRunner,\n): Promise<void> {\n  const files = config.snapshotSerializers\n\n  const snapshotSerializers = await Promise.all(\n    files.map(async (file) => {\n      const mo = await moduleRunner.import(file)\n      if (!mo || typeof mo.default !== 'object' || mo.default === null) {\n        throw new Error(\n          `invalid snapshot serializer file ${file}. Must export a default object`,\n        )\n      }\n\n      const config = mo.default\n      if (\n        typeof config.test !== 'function'\n        || (typeof config.serialize !== 'function'\n          && typeof config.print !== 'function')\n      ) {\n        throw new TypeError(\n          `invalid snapshot serializer in ${file}. Must have a 'test' method along with either a 'serialize' or 'print' method.`,\n        )\n      }\n\n      return config as SnapshotSerializer\n    }),\n  )","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/vitest/src/runtime/setup-common.ts#L56-L92","documentation":"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.","triggerScenarios":"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.","commonSituations":"Porting a Jest serializer that used a named export; forgetting `export default`; pointing the array at a non-serializer module by mistake.","solutions":["Default-export a serializer object: `export default { test: v => typeof v === 'string', serialize: (v, ...rest) => ... , print: undefined }`.","If the serializer is a named export, re-export as default: `export { mySerializer as default }`.","Confirm every entry in `snapshotSerializers` points to a real serializer file.","Remove the entry if a serializer is no longer needed."],"exampleFix":"// before — my-serializer.ts\nexport const mySerializer = { test() {}, serialize() {} }\n\n// after\nexport default { test() {}, serialize() {} }","handlingStrategy":"type-guard","validationCode":"async function loadSerializer(path: string) {\n  const mod = await import(/* @vite-ignore */ path)\n  if (!mod?.default || typeof mod.default !== 'object') {\n    throw new TypeError(`${path} must default-export a serializer object`)\n  }\n  return mod.default\n}","typeGuard":"function isSerializerObject(v: unknown): v is object {\n  return typeof v === 'object' && v !== null\n}","tryCatchPattern":null,"preventionTips":["Always `export default` the serializer object.","Keep one serializer per file for clarity.","Add a unit test asserting each serializer file default-exports an object."],"tags":["config","snapshot","serializer","validation","esm"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}