BabylonJS/Babylon.js · error

Failed to create canvas

Error message

Failed to create canvas

What it means

After loading the WebP image, LoadWebpImageData draws it onto a canvas created with engine.createCanvas() to extract raw RGBA pixels. If the engine cannot create a canvas of the requested size, this error is thrown. It means pixel extraction is impossible in the current environment.

Source

Thrown at packages/dev/loaders/src/SPLAT/sog.pure.ts:110

interface IWebPImage {
    bits: Uint8Array;
    width: number;
    height: number;
}
const SH_C0 = 0.28209479177387814;

async function LoadWebpImageData(rootUrlOrData: string | Uint8Array, filename: string, engine: AbstractEngine): Promise<IWebPImage> {
    const promise = new Promise<IWebPImage>((resolve, reject) => {
        const image = engine.createCanvasImage();
        if (!image) {
            throw new Error("Failed to create ImageBitmap");
        }
        image.onload = () => {
            try {
                // Draw to canvas
                const canvas = engine.createCanvas(image.width, image.height);
                if (!canvas) {
                    throw new Error("Failed to create canvas");
                }
                const ctx = canvas.getContext("2d");
                if (!ctx) {
                    throw new Error("Failed to get 2D context");
                }
                ctx.drawImage(image, 0, 0);

                // Extract pixel data (RGBA per pixel)
                const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
                resolve({ bits: new Uint8Array(imageData.data.buffer), width: imageData.width, height: imageData.height });
            } catch (error) {
                // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
                reject(`Error loading image ${image.src} with exception: ${error}`);
            }
        };
        image.onerror = (error) => {
            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
            reject(`Error loading image ${image.src} with exception: ${error}`);

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Add a canvas implementation (browser context or node-canvas polyfill).
  2. Check the WebP image dimensions; oversized images may exceed canvas limits — resize or re-encode the SOG asset.
  3. Confirm the engine's createCanvas is implemented (custom/NullEngine may not provide it).
  4. Catch the rejection inside the promise (this throw happens in an async callback, surfacing as a rejected promise).

Example fix

// before
const engine = new NullEngine();
await parseSog(data, engine); // createCanvas returns null -> error
// after
const engine = new Engine(canvasEl); // real canvas-backed engine
await parseSog(data, engine);
Defensive patterns

Strategy: fallback

Validate before calling

const probe = engine.createCanvas?.(1, 1);
if (!probe) {
  throw new Error("Engine cannot create canvases; SOG pixel extraction unavailable");
}

Type guard

function supportsCanvasCreation(engine: AbstractEngine): boolean {
  return typeof (engine as any).createCanvas === "function" && !!engine.createCanvas(1, 1);
}

Try / catch

try {
  const images = await loadWebpImages(url, engine);
} catch (e) {
  if (String(e.message) === "Failed to create canvas") {
    const bitmap = await createImageBitmap(await (await fetch(url)).blob());
    // draw bitmap onto a manually created OffscreenCanvas instead
  } else throw e;
}

Prevention

When it happens

Trigger: image.onload firing and engine.createCanvas(image.width, image.height) returning null/undefined — no canvas factory available or dimensions rejected.

Common situations: Headless Node environments without canvas polyfill; engines whose createCanvas implementation returns null for very large dimensions (e.g. WebP larger than max texture/canvas size).

Related errors


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