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

  1. Ensure the canvas is attached to the visible document before creating the renderer: `document.body.appendChild(engine.getRenderingCanvas())`.
  2. Defer renderer creation until after the canvas has layout (e.g. wait for DOMContentLoaded / requestAnimationFrame, or after removing `display:none`).
  3. 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

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


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/9c7e9ba6d35c98ba. Report an issue: GitHub.