{"record":{"id":"9d9f4acbe6e666f6","repo":"vitest-dev/vitest","slug":"invalid-snapshot-serializer-in-file-must-have","errorCode":null,"errorMessage":"invalid snapshot serializer in ${file}. Must have a 'test' method along with either a 'serialize' or 'print' method.","messagePattern":"invalid snapshot serializer in (.+?)\\. Must have a 'test' method along with either a 'serialize' or 'print' method\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/runtime/setup-common.ts","lineNumber":85,"sourceCode":"): 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  )\n\n  snapshotSerializers.forEach(serializer => addSerializer(serializer))\n}\n","sourceCodeStart":67,"sourceCodeEnd":96,"githubUrl":"https://github.com/vitest-dev/vitest/blob/1fa9837ec26533512fdcad8baebf249771bd340a/packages/vitest/src/runtime/setup-common.ts#L67-L96","documentation":"Thrown (as TypeError) by loadSnapshotSerializers after the default export is confirmed to be an object, if that object does not satisfy the SnapshotSerializer interface — specifically it must have a `test` function AND at least one of `serialize` or `print`. This mirrors Jest's serializer contract used by @vitest/snapshot's addSerializer.","triggerScenarios":"A snapshotSerializers entry default-exports an object that is missing `test`, missing both `serialize` and `print`, or where those keys are not functions (e.g. a plain config object was exported by mistake).","commonSituations":"Exporting a configuration object instead of a serializer; partially implementing the serializer interface; copy-paste errors that drop a method; version drift where a serializer was written against an older shape.","solutions":["Implement all required methods: a `test(val)` function plus either `serialize(val, config, indentation, depth, refs, printer)` or `print(val, printer)`.","Use `serialize` for full custom formatting; use `print` only when delegating to the built-in printer.","Confirm the exported object is the serializer itself, not settings for one."],"exampleFix":"// before\nexport default { test: 'yes' }\n\n// after\nexport default {\n  test: v => v?.constructor?.name === 'Money',\n  serialize: (val, config, indentation, depth, refs, printer) => {\n    return printer(`$${val.amount}`, config, indentation, depth, refs)\n  },\n}","handlingStrategy":"type-guard","validationCode":"function assertSerializer(v: unknown) {\n  const o = v as any\n  if (typeof o?.test !== 'function') throw new TypeError('serializer.test must be a function')\n  if (typeof o?.serialize !== 'function' && typeof o?.print !== 'function') {\n    throw new TypeError('serializer must have serialize or print')\n  }\n}","typeGuard":"type Serializer = { test: Function; serialize?: Function; print?: Function }\nfunction isSerializer(v: unknown): v is Serializer {\n  const o = v as any\n  return typeof o?.test === 'function'\n    && (typeof o?.serialize === 'function' || typeof o?.print === 'function')\n}","tryCatchPattern":null,"preventionTips":["Mirror Jest's serializer contract exactly: test + (serialize | print).","Write a smoke test importing each serializer file and asserting the method shape.","Prefer serialize over print unless delegating to the built-in printer."],"tags":["config","snapshot","serializer","validation","typeerror"],"backgroundTag":null,"analyzedSha":"1fa9837ec26533512fdcad8baebf249771bd340a","analyzedAt":"2026-08-11T16:11:39.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}