vitest-dev/vitest · error · Error
invalid snapshot serializer file ${file}. Must export a defa
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` does not have a default export that is a non-null object. Each serializer file must `export default { test, serialize/print }`. The default export is the serializer object Vitest registers via @vitest/snapshot's addSerializer.
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 d568f8ce37)
Solutions
- Use `export default { test, serialize }` in the serializer file.
- Confirm the path in `config.snapshotSerializers` resolves to the serializer file.
- Drop the file from snapshotSerializers if it was added by mistake.
- Migrate named-export serializers to default exports.
Example fix
// before (./my-serializer.js)
export const test = () => {}
export const serialize = () => {}
// after
export default {
test: val => typeof val === 'MyType',
serialize: (val, config, indent, depth, refs) => `MyType(${val.value})`,
} Defensive patterns
Strategy: type-guard
Validate before calling
import * as mod from './my-serializer.js'
if (!mod.default || typeof mod.default !== 'object') {
throw new Error('serializer must `export default { test, serialize|print }`')
} Type guard
function isSerializerFile(m: any): m is { default: object } {
return Boolean(m && m.default && typeof m.default === 'object')
} Prevention
- Standardize on `export default { test, serialize }`.
- Write a tiny test that imports each serializer and asserts its shape.
- Do not mix named-export Jest serializers without a default-export wrapper.
When it happens
Trigger: Listing a path under `test.snapshotSerializers: ['./my-serializer.js']` where the file has no default export, exports default as null, or exports default as a primitive/function. Importing a serializer that uses the older named-export convention.
Common situations: Porting a Jest-style snapshot serializer that used `module.exports = { ... }` incorrectly, or that used named exports. Forgetting `default` when converting CJS to ESM. Pointing at a util file that exports helper functions, not a serializer.
Related errors
- invalid snapshot serializer in ${file}. Must have a 'test' m
- Snapshot environment module must have a default export objec
- "snapshotFormat.compareKeys" function is not supported.
- Runner must export a default function, but got ${typeof mod.
- invalid diff config file ${config.diff}. Must have a default
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/a48571de734c3f65.json.
Report an issue: GitHub.