{"record":{"id":"dad869fcb2c6ad57","repo":"BabylonJS/Babylon.js","slug":"invalid-engine-unable-to-create-a-canvas-dad869","errorCode":null,"errorMessage":"Invalid engine. Unable to create a canvas.","messagePattern":"Invalid engine\\. Unable to create a canvas\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/gui/src/2D/controls/image.pure.ts","lineNumber":340,"sourceCode":"            return;\r\n        }\r\n\r\n        this._stretch = value;\r\n\r\n        this._markAsDirty();\r\n    }\r\n\r\n    /**\r\n     * @internal\r\n     */\r\n    public _rotate90(n: number, preserveProperties: boolean = false): Image {\r\n        const width = this._domImage.width;\r\n        const height = this._domImage.height;\r\n\r\n        // Should abstract platform instead of using LastCreatedEngine\r\n        const engine = this._host?.getScene()?.getEngine() || EngineStore.LastCreatedEngine;\r\n        if (!engine) {\r\n            throw new Error(\"Invalid engine. Unable to create a canvas.\");\r\n        }\r\n        const canvas = engine.createCanvas(height, width);\r\n\r\n        const context = canvas.getContext(\"2d\");\r\n\r\n        context.translate(canvas.width / 2, canvas.height / 2);\r\n        context.rotate((n * Math.PI) / 2);\r\n\r\n        context.drawImage(this._domImage, 0, 0, width, height, -width / 2, -height / 2, width, height);\r\n\r\n        const dataUrl: string = canvas.toDataURL(\"image/jpg\");\r\n        const rotatedImage = new Image(this.name + \"rotated\", dataUrl);\r\n\r\n        if (preserveProperties) {\r\n            rotatedImage._stretch = this._stretch;\r\n            rotatedImage._autoScale = this._autoScale;\r\n            rotatedImage._cellId = this._cellId;\r\n            rotatedImage._cellWidth = n % 1 ? this._cellHeight : this._cellWidth;\r","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/gui/src/2D/controls/image.pure.ts#L322-L358","documentation":"Image._rotate90 rotates the internal DOM image 90 degrees by drawing it onto an engine-created canvas (engine.createCanvas). It prefers the host scene's engine and falls back to EngineStore.LastCreatedEngine; with no engine available it throws because no 2D canvas surface can be created.","triggerScenarios":"Calling image.rotate90() (or APIs that trigger _rotate90) when the image's host has no scene/engine (e.g. sourceHost/linked GUI not yet attached) and EngineStore.LastCreatedEngine is null — engine-less, headless, or post-dispose contexts.","commonSituations":"Manipulating Image controls before the engine/scene exists; using the pure GUI build standalone; engine disposed while a delayed image-load callback rotates the image; unit tests without a Babylon engine.","solutions":["Create the engine/scene and attach the image to a GUI host before calling rotate90().","Ensure EngineStore.LastCreatedEngine exists (engine still alive) when the rotation runs.","If rotation is triggered from an image onload callback, guard against engine disposal or re-check engine availability.","In headless scenarios, provide a mock engine with createCanvas/getContext support."],"exampleFix":"// before\nconst img = new Image(\"img\", \"url.png\");\nimg.rotate90(); // no engine yet -> throws\n\n// after\nconst engine = new Engine(canvas, true);\nconst scene = new Scene(engine);\nconst adt = AdvancedDynamicTexture.CreateFullscreenUI(\"ui\", true, scene);\nconst img = new Image(\"img\", \"url.png\");\nadt.addControl(img);\nimg.rotate90();","handlingStrategy":"type-guard","validationCode":"const engine = image.host?.getScene()?.getEngine() ?? EngineStore.LastCreatedEngine;\nif (!engine) {\n    throw new Error(\"Engine required to rotate image\");\n}\nimage.rotate90();","typeGuard":"function canCreateCanvas(e: unknown): e is { createCanvas(w: number, h: number): HTMLCanvasElement } {\n    return !!e && typeof (e as any).createCanvas === \"function\";\n}","tryCatchPattern":"try {\n    image.rotate90();\n} catch (e) {\n    if (e instanceof Error && e.message.includes(\"Invalid engine\")) {\n        console.error(\"No engine available to create canvas for rotation:\", e);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Attach the Image control to a hosted GUI (ADT) with a live scene before mutating image orientation.","Verify the engine still exists inside async image-load callbacks before calling rotate90().","Initialize the engine before any image post-processing; keep engine dispose after GUI teardown.","Provide a mock engine in headless test environments."],"tags":["engine","canvas","image","gui","initialization-order"],"backgroundTag":"engine-not-initialized","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}