{"record":{"id":"9c7e9ba6d35c98ba","repo":"BabylonJS/Babylon.js","slug":"failed-to-get-client-rect-for-rendering-canvas","errorCode":null,"errorMessage":"Failed to get client rect for rendering canvas","messagePattern":"Failed to get client rect for rendering canvas","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/addons/src/htmlMesh/htmlMeshRenderer.ts","lineNumber":204,"sourceCode":"\r\n        // if the container already exists, then remove it\r\n        const inSceneContainerId = `${this._containerId}_in_scene`;\r\n        this._inSceneElements = this._createRenderLayerElements(inSceneContainerId);\r\n\r\n        parentContainer.insertBefore(this._inSceneElements.container, parentContainer.firstChild);\r\n\r\n        if (enableOverlayRender) {\r\n            const overlayContainerId = `${this._containerId}_overlay`;\r\n            this._overlayElements = this._createRenderLayerElements(overlayContainerId);\r\n            const zIndex = +(scene.getEngine().getRenderingCanvas()!.style.zIndex ?? \"0\") + 1;\r\n            this._overlayElements.container.style.zIndex = `${zIndex}`;\r\n            this._overlayElements.container.style.pointerEvents = \"none\";\r\n            parentContainer.insertBefore(this._overlayElements.container, parentContainer.firstChild);\r\n        }\r\n        this._engine = scene.getEngine();\r\n        const clientRect = this._engine.getRenderingCanvasClientRect();\r\n        if (!clientRect) {\r\n            throw new Error(\"Failed to get client rect for rendering canvas\");\r\n        }\r\n\r\n        // Set the size and resize behavior\r\n        this._setSize(clientRect.width, clientRect.height);\r\n\r\n        this._engine.onResizeObservable.add(() => {\r\n            const clientRect = this._engine.getRenderingCanvasClientRect();\r\n            if (clientRect) {\r\n                this._setSize(clientRect.width, clientRect.height);\r\n            }\r\n        });\r\n\r\n        let projectionObs: Observer<Camera>;\r\n        let matrixObs: Observer<Camera>;\r\n\r\n        const observeCamera = () => {\r\n            const camera = scene.activeCamera;\r\n            if (camera) {\r","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/addons/src/htmlMesh/htmlMeshRenderer.ts#L186-L222","documentation":"HtmlMeshRenderer's _init needs the canvas' on-page size (client rect) to size its HTML overlay container and subscribe to resizes. It calls engine.getRenderingCanvasClientRect(); if that returns null — the canvas is not attached to the DOM or has no layout — it cannot proceed and throws.","triggerScenarios":"Creating an HtmlMeshRenderer (whose constructor calls _init) while the engine's rendering canvas is detached from the document or `display: none`/not yet laid out, so getRenderingCanvasClientRect() returns null.","commonSituations":"Initializing the renderer before appending the canvas to the DOM; rendering into an offscreen/hidden canvas (e.g. inside a hidden tab or before first layout); using an engine created with a canvas element that was never added to the page.","solutions":["Ensure the canvas is attached to the visible document before creating the renderer: `document.body.appendChild(engine.getRenderingCanvas())`.","Defer renderer creation until after the canvas has layout (e.g. wait for DOMContentLoaded / requestAnimationFrame, or after removing `display:none`).","If the canvas must be offscreen, give it an explicit CSS size so it has a valid client rect, or use a fallback size for the overlay container."],"exampleFix":"// before\nconst engine = new BAB.Engine(canvas, true);\nconst renderer = new HtmlMeshRenderer(scene); // canvas not in DOM yet -> throws\n// after\ndocument.body.appendChild(canvas);\nawait new Promise((r) => requestAnimationFrame(r)); // let layout settle\nconst renderer = new HtmlMeshRenderer(scene);","handlingStrategy":"validation","validationCode":"const canvas = engine.getRenderingCanvas();\nif (!canvas || !canvas.isConnected || canvas.getClientRects().length === 0) {\n  throw new Error(\"canvas must be attached and visible before HtmlMeshRenderer\");\n}","typeGuard":"const hasClientRect = (c: HTMLCanvasElement | null): c is HTMLCanvasElement =>\n  !!c && c.isConnected && c.clientWidth > 0;","tryCatchPattern":"try {\n  renderer = new HtmlMeshRenderer(scene);\n} catch (e) {\n  if (String(e).includes(\"client rect\")) {\n    // defer creation until canvas is in DOM and laid out\n  } else throw e;\n}","preventionTips":["Append the engine canvas to the document before creating HTML-mesh renderers.","Avoid initializing inside hidden containers (display:none) or before first paint.","Wait for DOMContentLoaded/requestAnimationFrame before scene setup that needs layout."],"tags":["html-mesh","dom","canvas","layout","initialization"],"backgroundTag":"missing-dom-element","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}