{"record":{"id":"f983be06e7ce7869","repo":"emberjs/ember.js","slug":"attempted-to-cast-to-a-browser-node-in-a-non-brows","errorCode":null,"errorMessage":"Attempted to cast to a browser node in a non-browser context","messagePattern":"Attempted to cast to a browser node in a non-browser context","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@glimmer/debug-util/lib/simple-cast.ts","lineNumber":83,"sourceCode":"): NodeForSugaryCheck<S>;\nexport function castToBrowser<K extends keyof HTMLElementTagNameMap>(\n  element: SimpleElement | Element,\n  check: K\n): HTMLElementTagNameMap[K];\nexport function castToBrowser<S extends SugaryNodeCheck>(\n  node: SimpleNode | BrowserNode | null | undefined,\n  sugaryCheck?: S\n): 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)}`);","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/emberjs/ember.js/blob/26f97246a8bf2e28edf26ac3093da2e86c04ffc5/packages/@glimmer/debug-util/lib/simple-cast.ts#L65-L101","documentation":"castToBrowser is a debug utility that casts a value to a browser DOM node, checking it against the global `document`. In non-browser environments (SSR, Node tests, workers) `document` is undefined, so the cast is impossible and this error is thrown.","triggerScenarios":"Calling castToBrowser (directly or via input/option/marker helpers) when `typeof document === 'undefined'` — server-side rendering, Node-only unit tests, web workers.","commonSituations":"Running Glimmer SSR where code paths touch DOM-casting helpers; running tests in Node without jsdom; accidentally importing DOM utilities into server bundles.","solutions":["Only call castToBrowser in browser contexts; guard with `typeof document !== 'undefined'`","For SSR, use environment-agnostic code paths that skip DOM casting","Configure tests to run in a DOM environment (jsdom/happy-dom)","Polyfill a document if the environment is supposed to be browser-like"],"exampleFix":"// before\nlet node = castToBrowser(maybeNode, 'Element');\n// after\nif (typeof document !== 'undefined') {\n  let node = castToBrowser(maybeNode, 'Element');\n}","handlingStrategy":"type-guard","validationCode":"if (typeof document === 'undefined') {\n  throw new Error('castToBrowser requires a browser environment (document is undefined)');\n}","typeGuard":"function inBrowser(): boolean {\n  return typeof document !== 'undefined' && document.nodeType === 9;\n}","tryCatchPattern":"try {\n  node = castToBrowser(value, 'Element');\n} catch (e) {\n  if (String(e.message).includes('non-browser context')) {\n    node = null; // SSR path\n  } else { throw e; }\n}","preventionTips":["Branch on `typeof document` before any DOM-touching utility","Run SSR code paths in CI to catch DOM assumptions","Configure tests with jsdom/happy-dom when DOM APIs are needed"],"tags":["dom","ssr","environment","debug","node"],"backgroundTag":"document-undefined-server-side","analyzedSha":"26f97246a8bf2e28edf26ac3093da2e86c04ffc5","analyzedAt":"2026-09-01T05:01:28.182Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}