{"record":{"id":"36d778259fdc71a5","repo":"BabylonJS/Babylon.js","slug":"failed-to-create-canvas","errorCode":null,"errorMessage":"Failed to create canvas","messagePattern":"Failed to create canvas","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/SPLAT/sog.pure.ts","lineNumber":110,"sourceCode":"interface IWebPImage {\r\n    bits: Uint8Array;\r\n    width: number;\r\n    height: number;\r\n}\r\nconst SH_C0 = 0.28209479177387814;\r\n\r\nasync function LoadWebpImageData(rootUrlOrData: string | Uint8Array, filename: string, engine: AbstractEngine): Promise<IWebPImage> {\r\n    const promise = new Promise<IWebPImage>((resolve, reject) => {\r\n        const image = engine.createCanvasImage();\r\n        if (!image) {\r\n            throw new Error(\"Failed to create ImageBitmap\");\r\n        }\r\n        image.onload = () => {\r\n            try {\r\n                // Draw to canvas\r\n                const canvas = engine.createCanvas(image.width, image.height);\r\n                if (!canvas) {\r\n                    throw new Error(\"Failed to create canvas\");\r\n                }\r\n                const ctx = canvas.getContext(\"2d\");\r\n                if (!ctx) {\r\n                    throw new Error(\"Failed to get 2D context\");\r\n                }\r\n                ctx.drawImage(image, 0, 0);\r\n\r\n                // Extract pixel data (RGBA per pixel)\r\n                const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\r\n                resolve({ bits: new Uint8Array(imageData.data.buffer), width: imageData.width, height: imageData.height });\r\n            } catch (error) {\r\n                // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                reject(`Error loading image ${image.src} with exception: ${error}`);\r\n            }\r\n        };\r\n        image.onerror = (error) => {\r\n            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n            reject(`Error loading image ${image.src} with exception: ${error}`);\r","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/SPLAT/sog.pure.ts#L92-L128","documentation":"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.","triggerScenarios":"image.onload firing and engine.createCanvas(image.width, image.height) returning null/undefined — no canvas factory available or dimensions rejected.","commonSituations":"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).","solutions":["Add a canvas implementation (browser context or node-canvas polyfill).","Check the WebP image dimensions; oversized images may exceed canvas limits — resize or re-encode the SOG asset.","Confirm the engine's createCanvas is implemented (custom/NullEngine may not provide it).","Catch the rejection inside the promise (this throw happens in an async callback, surfacing as a rejected promise)."],"exampleFix":"// before\nconst engine = new NullEngine();\nawait parseSog(data, engine); // createCanvas returns null -> error\n// after\nconst engine = new Engine(canvasEl); // real canvas-backed engine\nawait parseSog(data, engine);","handlingStrategy":"fallback","validationCode":"const probe = engine.createCanvas?.(1, 1);\nif (!probe) {\n  throw new Error(\"Engine cannot create canvases; SOG pixel extraction unavailable\");\n}","typeGuard":"function supportsCanvasCreation(engine: AbstractEngine): boolean {\n  return typeof (engine as any).createCanvas === \"function\" && !!engine.createCanvas(1, 1);\n}","tryCatchPattern":"try {\n  const images = await loadWebpImages(url, engine);\n} catch (e) {\n  if (String(e.message) === \"Failed to create canvas\") {\n    const bitmap = await createImageBitmap(await (await fetch(url)).blob());\n    // draw bitmap onto a manually created OffscreenCanvas instead\n  } else throw e;\n}","preventionTips":["Verify engine.createCanvas exists and returns non-null in your environment before SOG loads.","Avoid NullEngine/headless engines for asset pipelines that decode pixels.","Check WebP dimensions against canvas size limits; re-encode oversized images.","Provide a createImageBitmap-based fallback decoder for constrained environments."],"tags":["splat","sog","canvas","environment"],"backgroundTag":"canvas-not-supported","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}