vitest-dev/vitest · error · Error
Cannot provide "${key}" because it's not serializable.
Error message
Cannot provide "${key}" because it's not serializable. What it means
Vitest's project.provide() injects values into the test context via inject(), but those values cross a process boundary (worker threads / child processes) and so must be structured-cloneable. The method (project.ts:124) runs structuredClone(value) as a guard and rethrows with this message when it fails. Non-cloneable values (functions, DOM nodes, class instances with non-cloneable internals, objects with circular refs) cannot be delivered to tests.
Source
Thrown at packages/vitest/src/node/project.ts:132
this._fetcher,
this.config,
)
}
// "provide" is a property, not a method to keep the context when destructed in the global setup,
// making it a method would be a breaking change, and can be done in Vitest 3 at minimum
/**
* Provide a value to the test context. This value will be available to all tests with `inject`.
*/
provide = <T extends keyof ProvidedContext & string>(
key: T,
value: ProvidedContext[T],
): void => {
try {
structuredClone(value)
}
catch (err) {
throw new Error(
`Cannot provide "${key}" because it's not serializable.`,
{
cause: err,
},
)
}
// casting `any` because the default type is `never` since `ProvidedContext` is empty
(this._provided as any)[key] = value
}
/**
* Get the provided context. The project context is merged with the global context.
*/
getProvidedContext(): ProvidedContext {
if (this.isRootProject()) {
return this._provided
}
// globalSetup can run even if core workspace is not part of the test runView on GitHub (pinned to d568f8ce37)
Solutions
- Provide only plain serializable data: strings, numbers, booleans, arrays, plain objects, Date, RegExp, Map, Set, ArrayBuffer, TypedArrays.
- If you must pass a non-serializable resource, provide a factory pattern: provide a config descriptor (URLs, options) and construct the resource inside setup() or the test instead.
- Run structuredClone(value) yourself in a try/catch before calling provide to surface the exact clone failure and the offending key.
- For functions, use vi.fn() only inside tests; never inject live spies across the boundary.
Example fix
// before
project.provide('db', openDatabaseConnection())
// after
project.provide('dbConfig', { url: 'postgres://...', pool: 10 })
// construct the connection inside setupFiles or the test Defensive patterns
Strategy: validation
Validate before calling
function isSerializable(value) {
try { structuredClone(value); return true } catch { return false }
}
// before provide:
if (!isSerializable(value)) throw new Error(`Refusing to provide non-serializable value for key '${key}'`)
project.provide(key, value) Type guard
function isStructuredCloneable<T>(v: T): boolean {
try { structuredClone(v); return true } catch { return false }
} Try / catch
try {
project.provide(key, value)
} catch (e) {
if (e instanceof Error && /not serializable/.test(e.message)) {
// fall back to a serializable descriptor instead of the live object
} else throw e
} Prevention
- Only provide plain JSON-like data; construct resources inside tests/setupFiles.
- Run a pre-flight structuredClone over the whole provide object in a config plugin.
- Document which keys are injectable and their expected (serializable) shape.
When it happens
Trigger: Calling project.provide('myKey', value) where value is a function, a class instance holding a non-cloneable field, a cyclic object, a WeakMap/WeakSet, or any value structuredClone rejects. Also triggered indirectly via config.provide in the test config object.
Common situations: Passing a database connection handle, an Express app instance, a logger with open sockets, a function/callback, or a reactive store wrapper (e.g. a Vue ref's internals) into provide(). Also hits when provide receives an object that secretly contains a circular reference.
Related errors
- Cannot take a screenshot without a test path
- stopChunkTrace cannot be called outside of the test file.
- This command can only be called inside a test file.
- Cannot upload files outside of a test
- Cannot take a screenshot outside of a test.
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/61d1af47d12faa4e.json.
Report an issue: GitHub.