vitest-dev/vitest · error · TypeError
invalid snapshot serializer in ${file}. Must have a 'test' m
Error message
invalid snapshot serializer in ${file}. Must have a 'test' method along with either a 'serialize' or 'print' method. What it means
Thrown by loadSnapshotSerializers (as a TypeError) when the serializer's default object exists but does not conform to the required interface: it must have a `test` function AND either a `serialize` or a `print` function. These mirror Jest's snapshot serializer contract used by @vitest/snapshot.
Source
Thrown at packages/vitest/src/runtime/setup-common.ts:85
): 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
}),
)
snapshotSerializers.forEach(serializer => addSerializer(serializer))
}
View on GitHub (pinned to d568f8ce37)
Solutions
- Ensure the default object has `test(val): boolean`.
- Add exactly one of `serialize(val, config, indent, depth, refs, printer)` or `print(val, printer)` with those exact names.
- Double-check method spelling: it is `serialize`/`print`, not `serialise`/`printValue`.
- Reference Jest's snapshot serializer docs - Vitest mirrors that API.
Example fix
// before
export default {
serialize: (val) => `Foo(${val})`,
// missing test
}
// after
export default {
test: val => val?.constructor?.name === 'Foo',
serialize: (val, config, indent, depth, refs, printer) => `Foo(${printer(val.value, config, indent, depth, refs)})`,
} Defensive patterns
Strategy: type-guard
Validate before calling
import serializerDefault from './my-serializer.js'
const s = serializerDefault as any
if (typeof s.test !== 'function' || (typeof s.serialize !== 'function' && typeof s.print !== 'function')) {
throw new Error('serializer must have test() and serialize()|print()')
} Type guard
function isSerializer(v: unknown): v is { test: Function; serialize?: Function; print?: Function } {
if (!v || typeof v !== 'object') return false
const o = v as any
return typeof o.test === 'function' && (typeof o.serialize === 'function' || typeof o.print === 'function')
} Prevention
- Always include `test` and exactly one of serialize/print.
- Keep method names exactly test/serialize/print.
- Mirror the Jest snapshot serializer API to stay compatible.
When it happens
Trigger: A serializer default object that has `serialize` but no `test`. One that has `test` but neither `serialize` nor `print`. A serializer that exports `{ print }` only (no test). Misnaming the methods (e.g. `serializeValue` instead of `serialize`).
Common situations: Hand-writing a serializer from memory and forgetting `test`. Copying a partial example. Renaming methods during a refactor. Confusing this with the expect.addSnapshotSerializer inline shape.
Related errors
- invalid snapshot serializer file ${file}. Must export a defa
- The snapshot state for '${filepath}' is not found. Did you c
- Environment "${name}" is not a valid environment. Path "${pa
- Snapshot environment module must have a default export objec
- Tag "${tag.name}": priority must be a non-negative number.
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/9d9f4acbe6e666f6.json.
Report an issue: GitHub.