{"record":{"id":"0060f4f53d054046","repo":"karatelabs/karate","slug":"datacloneerror-a-type-could-not-be-cloned","errorCode":null,"errorMessage":"DataCloneError: a ${type} could not be cloned","messagePattern":"DataCloneError: a (.+?) could not be cloned","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsStructuredClone.java","lineNumber":65,"sourceCode":"\n    private static final byte DATA_ATTRS = JsObject.WRITABLE | JsObject.CONFIGURABLE;\n\n    private JsStructuredClone() {\n    }\n\n    static Object call(Context context, Object[] args) {\n        if (args.length == 0) {\n            throw JsErrorException.typeError(\"structuredClone requires at least 1 argument\");\n        }\n        // args[1] is the options bag carrying `transfer` — nothing in this\n        // engine is transferable, so it is accepted and ignored\n        return clone(args[0], new IdentityHashMap<>(), context instanceof CoreContext cc ? cc : null);\n    }\n\n    private static Object clone(Object value, IdentityHashMap<Object, Object> memo, CoreContext ctx) {\n        String type = Terms.typeOf(value);\n        if (\"function\".equals(type) || \"symbol\".equals(type)) {\n            throw dataCloneError(type);\n        }\n        Object seen = memo.get(value);\n        if (seen != null) {\n            return seen;\n        }\n        if (value instanceof JsPrimitive jp) {\n            return remember(memo, value, boxed(jp));\n        }\n        if (value instanceof JsDate d) {\n            return remember(memo, value, new JsDate(d.getTimeValue()));\n        }\n        if (value instanceof JsRegex r) {\n            return remember(memo, value, new JsRegex(r.pattern, r.flags));\n        }\n        if (value instanceof JsArray a) {\n            JsArray copy = new JsArray(new ArrayList<>(a.list.size()));\n            memo.put(value, copy);\n            // jsEntries is the spec own-key walk: holes are skipped, index","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsStructuredClone.java#L47-L83","documentation":"The structured clone algorithm (JsStructuredClone) cannot copy values of type `function` or `symbol`, matching the HTML spec's DataCloneError. When clone() encounters such a value via typeOf it throws \"DataCloneError: a ${type} could not be cloned\". This occurs in postMessage-style messaging, worker-style APIs, or any structured-clone copy operation.","triggerScenarios":"Calling the structured-clone entry (clone/call/copyOwn) with an argument that is a function or a symbol, or an object graph containing one (e.g. passing a callback through a message).","commonSituations":"Passing callbacks or class methods through message passing APIs; including symbols as object keys in payloads intended for cloning; porting Node/browser structuredClone code that hit the same rule.","solutions":["Remove functions/symbols from the data being cloned; send plain data (objects, arrays, primitives).","Pass function references separately (e.g. by name) and resolve them on the receiving side.","Convert symbol-keyed data to string keys before cloning."],"exampleFix":"// before\nchannel.postMessage({ callback: function () { ... } });\n\n// after\nchannel.postMessage({ callbackName: 'myHandler' }); // resolve by name on receiver","handlingStrategy":"type-guard","validationCode":"// before cloning, assert the payload is data-only\nfunction isCloneable(v) {\n  return v === null || ['string','number','boolean','undefined'].includes(typeof v)\n    || (Array.isArray(v) && v.every(isCloneable))\n    || (typeof v === 'object' && Object.values(v).every(isCloneable));\n}","typeGuard":"function isCloneable(v) {\n  if (typeof v === 'function' || typeof v === 'symbol') return false;\n  if (v === null || typeof v !== 'object') return true;\n  return Object.values(v).every(isCloneable);\n}","tryCatchPattern":null,"preventionTips":["Treat message payloads as plain data (POJOs): no functions, symbols, or class instances with methods.","Pass functions by name/reference separately from cloned data.","Add a validation step that walks the payload before postMessage/clone."],"tags":["javascript","structured-clone","data"],"backgroundTag":"data-clone-error","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}