{"record":{"id":"d1febf552f10e7cc","repo":"denoland/deno","slug":"datacloneerror-d1febf","errorCode":"DataCloneError","errorMessage":"Cannot clone object of unsupported type.","messagePattern":"Cannot clone object of unsupported type\\.","errorType":"exception","errorClass":"DOMException","httpStatus":null,"severity":"error","filePath":"ext/web/13_message_port.js","lineNumber":310,"sourceCode":"   * @param {object[] | StructuredSerializeOptions} transferOrOptions\n   */\n  postMessage(message, transferOrOptions = { __proto__: null }) {\n    webidl.assertBranded(this, MessagePortPrototype);\n    const prefix = \"Failed to execute 'postMessage' on 'MessagePort'\";\n    webidl.requiredArguments(arguments.length, 1, prefix);\n    const portId = getMessagePortId(this);\n    const portClosed = portId === null;\n    // Fast path: no transferables - serialize and send in one shot,\n    // bypassing the JsMessageData serde overhead\n    if (\n      transferOrOptions === undefined ||\n      transferOrOptions === null ||\n      (arguments.length <= 1)\n    ) {\n      if (portClosed) return;\n      // Honor markAsUncloneable for top-level postMessage values.\n      if (isUncloneable(message)) {\n        throw new DOMException(\n          \"Cannot clone object of unsupported type.\",\n          \"DataCloneError\",\n        );\n      }\n      const data = serializeMessageData(message, serializeErrorCb);\n      const currentPortId = getMessagePortId(this);\n      if (currentPortId === null) return;\n      op_message_port_post_message_raw(currentPortId, data);\n      return;\n    }\n    message = webidl.converters.any(message);\n    let options;\n    if (\n      webidl.type(transferOrOptions) === \"Object\" &&\n      transferOrOptions !== undefined &&\n      transferOrOptions[SymbolIterator] !== undefined\n    ) {\n      const transfer = webidl.converters[\"sequence<object>\"](","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/web/13_message_port.js#L292-L328","documentation":"On MessagePort.postMessage's fast path (no transfer list, at most one argument), the top-level message is checked with the internal `isUncloneable` helper (ext/web/13_message_port.js:308-316). Values whose prototype was marked not-serializable (Web API platform types such as URL, Headers, Request) or that were flagged per-instance via node:worker_threads `markAsUncloneable()` throw DataCloneError \"Cannot clone object of unsupported type.\" before V8's serializer runs — without this check they would silently clone as `{}`.","triggerScenarios":"`port.postMessage(new URL('https://example.com'))` with no second argument; posting a Request/Headers instance or a markAsUncloneable-flagged object as the entire message.","commonSituations":"Sending live web-platform objects between workers instead of plain data; Node-compat worker_threads code relying on markAsUncloneable semantics; refactors that forward framework objects through postMessage.","solutions":["Post plain serializable data: convert first (url.href, headers-to-array, JSON string).","If the value is genuinely transferable (ArrayBuffer, another MessagePort), list it in the transfer list instead of relying on cloning.","Run a `structuredClone` probe on unknown payloads before posting to fail early with a clear context."],"exampleFix":"// before\nport.postMessage(new URL(\"https://example.com\"));\n\n// after\nport.postMessage(new URL(\"https://example.com\").href);","handlingStrategy":"try-catch","validationCode":"function isCloneableTopLevel(v) {\n  if (v === null) return true;\n  const t = typeof v;\n  if (t !== \"object\" && t !== \"function\") return true; // primitives always clone\n  try {\n    structuredClone(v);\n    return true;\n  } catch {\n    return false;\n  }\n}\nif (!isCloneableTopLevel(msg)) msg = toPlainData(msg);","typeGuard":"const isPlainMessage = (v) => v === null || [\"string\", \"number\", \"boolean\", \"bigint\", \"undefined\"].includes(typeof v);","tryCatchPattern":"try {\n  port.postMessage(msg);\n} catch (e) {\n  if (e instanceof DOMException && e.name === \"DataCloneError\") {\n    port.postMessage(toPlainData(msg)); // strip platform objects, retry\n  } else {\n    throw e;\n  }\n}","preventionTips":["Post data-only payloads (POJOs, primitives) across MessagePorts.","Convert platform objects before posting: url.href, headers-to-entries, awaited bodies.","Fail fast: probe unknown payloads with structuredClone before posting so errors carry your context."],"tags":["messageport","postmessage","structured-clone","datacloneerror"],"backgroundTag":"data-clone-error","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}