BabylonJS/Babylon.js · error · Error
Failed to get client rect for rendering canvas
Error message
Failed to get client rect for rendering canvas
What it means
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.
Source
Thrown at packages/dev/addons/src/htmlMesh/htmlMeshRenderer.ts:204
// if the container already exists, then remove it
const inSceneContainerId = `${this._containerId}_in_scene`;
this._inSceneElements = this._createRenderLayerElements(inSceneContainerId);
parentContainer.insertBefore(this._inSceneElements.container, parentContainer.firstChild);
if (enableOverlayRender) {
const overlayContainerId = `${this._containerId}_overlay`;
this._overlayElements = this._createRenderLayerElements(overlayContainerId);
const zIndex = +(scene.getEngine().getRenderingCanvas()!.style.zIndex ?? "0") + 1;
this._overlayElements.container.style.zIndex = `${zIndex}`;
this._overlayElements.container.style.pointerEvents = "none";
parentContainer.insertBefore(this._overlayElements.container, parentContainer.firstChild);
}
this._engine = scene.getEngine();
const clientRect = this._engine.getRenderingCanvasClientRect();
if (!clientRect) {
throw new Error("Failed to get client rect for rendering canvas");
}
// Set the size and resize behavior
this._setSize(clientRect.width, clientRect.height);
this._engine.onResizeObservable.add(() => {
const clientRect = this._engine.getRenderingCanvasClientRect();
if (clientRect) {
this._setSize(clientRect.width, clientRect.height);
}
});
let projectionObs: Observer<Camera>;
let matrixObs: Observer<Camera>;
const observeCamera = () => {
const camera = scene.activeCamera;
if (camera) {
View on GitHub (pinned to 0592b347b8)
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.
Example fix
// before const engine = new BAB.Engine(canvas, true); const renderer = new HtmlMeshRenderer(scene); // canvas not in DOM yet -> throws // after document.body.appendChild(canvas); await new Promise((r) => requestAnimationFrame(r)); // let layout settle const renderer = new HtmlMeshRenderer(scene);
Defensive patterns
Strategy: validation
Validate before calling
const canvas = engine.getRenderingCanvas();
if (!canvas || !canvas.isConnected || canvas.getClientRects().length === 0) {
throw new Error("canvas must be attached and visible before HtmlMeshRenderer");
} Type guard
const hasClientRect = (c: HTMLCanvasElement | null): c is HTMLCanvasElement => !!c && c.isConnected && c.clientWidth > 0;
Try / catch
try {
renderer = new HtmlMeshRenderer(scene);
} catch (e) {
if (String(e).includes("client rect")) {
// defer creation until canvas is in DOM and laid out
} else throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Atmosphere is not supported on WebGL ${engine.version}.
- Atmosphere only supports one light source currently.
- Unable to get 2d context
- The provided canvas is null or undefined.
- Draco: Decoder module is not available
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/9c7e9ba6d35c98ba.
Report an issue: GitHub.