BabylonJS/Babylon.js · error · Error
The provided canvas is null or undefined.
Error message
The provided canvas is null or undefined.
What it means
ThinEngine's constructor throws this when the engine could not obtain a WebGL context AND the canvas argument passed in is null or undefined. Before attempting canvas.getContext('webgl'), the code guards that a canvas exists; if none was given the engine cannot proceed at all.
Source
Thrown at packages/dev/core/src/Engines/thinEngine.pure.ts:383
this._gl = <any>(canvas.getContext("webgl2", options) || canvas.getContext("experimental-webgl2", options));
if (this._gl) {
this._webGLVersion = 2.0;
this._shaderPlatformName = "WEBGL2";
// Prevent weird browsers to lie (yeah that happens!)
if (!this._gl.deleteQuery) {
this._webGLVersion = 1.0;
this._shaderPlatformName = "WEBGL1";
}
}
} catch (e) {
// Do nothing
}
}
if (!this._gl) {
if (!canvas) {
throw new Error("The provided canvas is null or undefined.");
}
try {
this._gl = <WebGL2RenderingContext>(canvas.getContext("webgl", options) || canvas.getContext("experimental-webgl", options));
} catch (e) {
throw new Error("WebGL not supported", { cause: e });
}
}
if (!this._gl) {
throw new Error("WebGL not supported");
}
} else {
this._gl = <WebGL2RenderingContext>canvasOrContext;
canvas = this._gl.canvas as HTMLCanvasElement;
if ((this._gl as any).renderbufferStorageMultisample) {
this._webGLVersion = 2.0;
this._shaderPlatformName = "WEBGL2";
View on GitHub (pinned to 0592b347b8)
Solutions
- Pass a real canvas element (or an existing WebGL context) to the Engine constructor
- Ensure the DOM is loaded before querying the canvas (script at end of body or DOMContentLoaded)
- Check that document.getElementById/getElementByClassName returns the intended element
- Null-check the canvas before constructing the engine
Example fix
// before
const canvas = document.getElementById('renderCanvas'); // null if id typo / not in DOM yet
const engine = new Engine(canvas, true);
// after
const canvas = document.getElementById('renderCanvas') as HTMLCanvasElement;
if (!canvas) throw new Error('renderCanvas element missing');
const engine = new Engine(canvas, true); Defensive patterns
Strategy: type-guard
Validate before calling
function requireCanvas(el: HTMLElement | null | undefined): HTMLCanvasElement {
if (!el || !(el instanceof HTMLCanvasElement)) throw new Error('Valid canvas element required');
return el;
} Type guard
function isCanvas(v: unknown): v is HTMLCanvasElement {
return typeof HTMLCanvasElement !== 'undefined' && v instanceof HTMLCanvasElement;
} Try / catch
try {
const engine = new Engine(canvas as HTMLCanvasElement, true);
} catch (e) {
if ((e as Error).message.includes('canvas is null')) {
console.error('Canvas element missing — check DOM id and load order');
}
} Prevention
- Initialize the engine after DOMContentLoaded or place scripts at end of body
- Log document.getElementById(...) results during setup debugging
- Type the canvas parameter as HTMLCanvasElement so null is caught at compile time
- Centralize engine creation in one factory function with canvas validation
When it happens
Trigger: new Engine(null), new Engine(undefined), passing a variable that is not yet assigned, or passing the result of a failed lookup (e.g. document.getElementById('missing')) which returns null.
Common situations: DOM element queried before it exists (script running before DOM ready); typo in canvas element id; passing null deliberately in tests; refactoring code so the canvas variable is uninitialized at engine construction.
Related errors
- Unable to get 2d context
- Atmosphere is not supported on WebGL ${engine.version}.
- Sample2DRgbaToRef: widthPx and heightPx must be positive.
- Sample2DRgbaToRef: data length (${data.length}) is less than
- Failed to get client rect for rendering canvas
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/f375e44225f2b19a.
Report an issue: GitHub.