Error: postMessage could not be cloned — DataCloneError in worker_threads
Quick answer
Like structuredClone(), worker_threads' postMessage() uses the structured clone algorithm under the hood, so it can't send functions, class instances, or open handles across the thread boundary. Pass plain data, or use transferable objects (like ArrayBuffer) for large binary payloads instead of copying them.
What causes this error
Worker and MessagePort communicate by serializing data with the structured clone algorithm — the exact same rules as structuredClone() and the browser's `postMessage`. Anything non-clonable (functions, class instances with native bindings, live sockets) throws immediately when you try to send it.
The Fix
import { Worker } from 'node:worker_threads';
const worker = new Worker('./worker.js');
// Wrong — sending a class instance with methods
worker.postMessage(new HeavyProcessor(options)); // DataCloneError
// Fix — send plain data, reconstruct inside the worker if needed
worker.postMessage({ options }); // plain object, always clonable
// For large binary data, transfer ownership instead of copying it
const buffer = new ArrayBuffer(1024 * 1024);
worker.postMessage({ buffer }, [buffer]); // second arg = transfer listCommon causes / variations
- Sending an ORM/database model instance instead of its plain field values
- Trying to send a callback function expecting the worker to invoke it (workers can't receive functions — use message-based request/response instead)
- Forgetting the transfer list for large `ArrayBuffer`s, causing a slow full copy instead of a zero-copy transfer
Related errors
See also: DataCloneError from structuredClone(), Only plain objects can be passed to Client Components.
Was this fix helpful?
Comments
Loading comments...