-
Notifications
You must be signed in to change notification settings - Fork 198
postMessage with MessagePort transfer fails in Firefox with DataCloneError #3077
Description
Description
When an application running under Hammerhead's proxy calls postMessage with MessagePort objects in the transfer list, Firefox throws:
DataCloneError: The object could not be cloned.
or:
MessagePort object could not be cloned.
This happens because MessageSandbox.postMessage wraps the original message in a Hammerhead envelope object before forwarding it via fastApply. The structured clone algorithm in Firefox cannot reconcile the wrapped envelope with the transferable MessagePort objects in the transfer list — the ports reference the original message, not the wrapped one.
Additionally, the postMessage(message, { targetOrigin, transfer }) overload (the modern options-based API) is not supported. When the second argument is an object, the call is silently dropped.
Steps to Reproduce
- Create a page with an iframe
- Set up a
MessageChannelbetween the parent and iframe - Use
postMessage(message, targetOrigin, [channel.port1])or the modernpostMessage(message, { targetOrigin: '*', transfer: [channel.port1] })to transfer aMessagePortto the iframe - Run this under TestCafe using Firefox (not native automation)
Expected Behavior
The MessagePort is successfully transferred to the iframe, and both sides can communicate over the channel.
Actual Behavior
Firefox throws DataCloneError: MessagePort object could not be cloned. The message is never delivered and the communication channel is broken.
This works correctly in Chrome because TestCafe uses native automation (CDP) for Chrome, which bypasses Hammerhead's proxy entirely.
Environment
- TestCafe version: 3.7.2
- testcafe-hammerhead: 31.7.7
- Browser: Firefox (ESR and stable)
- OS: macOS, Linux (Docker)
Root Cause Analysis
In MessageSandbox.postMessage, the method wraps the user message in a { message, originUrl, targetUrl, type } envelope before calling fastApply. When the transfer list includes MessagePort objects, Firefox's structured clone fails because:
- The transferable ports are associated with the original message, not the envelope
- The envelope object cannot be structured-cloned alongside the original transferables
Additionally, when postMessage(message, options) is called with an object second argument, the code treats it as a non-string targetOrigin and returns null, silently dropping the call.