{"record":{"id":"4729bc154f6f1d03","repo":"emberjs/ember.js","slug":"attempted-to-cast-to-a-browser-node-with-a-node-th","errorCode":null,"errorMessage":"Attempted to cast to a browser node with a node that was not created from this document","messagePattern":"Attempted to cast to a browser node with a node that was not created from this document","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@glimmer/debug-util/lib/simple-cast.ts","lineNumber":91,"sourceCode":"): Document | NodeForSugaryCheck<S> | null {\n  if (!LOCAL_DEBUG) {\n    return node as Document | NodeForSugaryCheck<S> | null;\n  }\n\n  if (node === null || node === undefined) {\n    return null;\n  }\n\n  if (typeof document === 'undefined') {\n    throw new Error('Attempted to cast to a browser node in a non-browser context');\n  }\n\n  if (isDocument(node)) {\n    return node as Document;\n  }\n\n  if (node.ownerDocument !== document) {\n    throw new Error(\n      'Attempted to cast to a browser node with a node that was not created from this document'\n    );\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme\n  return checkBrowserNode(node, sugaryCheck!);\n}\n\nfunction checkError(from: string, check: SugaryNodeCheck): Error {\n  return new Error(`cannot cast a ${from} into ${String(check)}`);\n}\n\nexport const ELEMENT_NODE = 1;\nexport const DOCUMENT_NODE = 9;\n\nfunction isDocument(node: Node | SimpleNode | SimpleDocument): node is Document | SimpleDocument {\n  return node.nodeType === DOCUMENT_NODE;\n}","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/emberjs/ember.js/blob/26f97246a8bf2e28edf26ac3093da2e86c04ffc5/packages/@glimmer/debug-util/lib/simple-cast.ts#L73-L109","documentation":"castToBrowser verifies that the node's ownerDocument matches the current global document. When a node was created by a different document (e.g. an iframe, jsdom instance, or detached document), the cast is rejected to prevent cross-document DOM mixing, which causes subtle browser bugs.","triggerScenarios":"Passing a node created in an iframe or another Document instance to castToBrowser; mixing jsdom documents across test files; moving nodes between windows.","commonSituations":"Testing with multiple jsdom instances; code that clones or adopts nodes across iframes; browser extension content scripts operating on elements from different documents.","solutions":["Ensure nodes are created via the same global document the app runs in","Use `document.importNode` / `adoptNode` to move nodes between documents before casting","In tests, use a single shared jsdom document","Avoid caching DOM nodes across iframe reloads"],"exampleFix":"// before\nlet el = iframe.contentDocument.createElement('div');\ncastToBrowser(el, 'Element');\n// after\nlet el = document.importNode(iframe.contentDocument.createElement('div'), true);\ncastToBrowser(el, 'Element');","handlingStrategy":"validation","validationCode":"function isFromCurrentDocument(node) {\n  return node != null && node.ownerDocument === document;\n}","typeGuard":"function isLocalNode(node) { return node != null && typeof node === 'object' && node.ownerDocument === document; }","tryCatchPattern":"try {\n  node = castToBrowser(value, 'Element');\n} catch (e) {\n  if (String(e.message).includes('not created from this document')) {\n    node = document.importNode(value, true);\n  } else { throw e; }\n}","preventionTips":["Never create DOM nodes with foreign documents (iframes) and use them in the main document","Use document.importNode/adoptNode for cross-document moves","Share a single jsdom instance across tests"],"tags":["dom","document","iframe","debug","cross-document"],"backgroundTag":"dom-node-wrong-document","analyzedSha":"26f97246a8bf2e28edf26ac3093da2e86c04ffc5","analyzedAt":"2026-09-01T05:01:28.182Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}