AvaloniaUI/Avalonia · critical · Error

Module.GL object wasn't initialized, WebGL can't be used.

Error message

Module.GL object wasn't initialized, WebGL can't be used.

What it means

Thrown by the WebGlRenderTarget constructor when getGL() returns a falsy value. getGL() looks for the Emscripten Module.GL object (or global AvaloniaGL/SkiaSharpGL shims) that Skia uses to wrap a WebGL context for Emscripten interop. A null result means none of those interop hooks are present on the global object.

Source

Thrown at src/Browser/Avalonia.Browser/webapp/modules/avalonia/rendering/webGlRenderTarget.ts:32

    const self = globalThis as any;
    const module = self.Module ?? self.getDotnetRuntime(0)?.Module;
    return (module?.GL ?? self.AvaloniaGL ?? self.SkiaSharpGL) as EmscriptenGL;
}

export class WebGlRenderTarget extends WebRenderTarget {
    public contextHandle?: number;
    public attrs: WebGLContextAttributes;
    public fboId?: number;
    public stencil?: number;
    public sample?: number;
    public depth?: number;
    private static _gl: EmscriptenGL | null = null;

    constructor(public canvas: HTMLCanvasElement | OffscreenCanvas, mode: BrowserRenderingMode) {
        // Skia only understands WebGL context wrapped in Emscripten.
        if (WebGlRenderTarget._gl == null) { WebGlRenderTarget._gl = getGL(); }
        if (!WebGlRenderTarget._gl) {
            throw new Error("Module.GL object wasn't initialized, WebGL can't be used.");
        }

        const attrs: WebGLContextAttributes | any =
            {
                alpha: true,
                depth: true,
                stencil: true,
                antialias: false,
                premultipliedAlpha: true,
                preserveDrawingBuffer: false,
                // only supported on older browsers, which is perfect as we want to fallback to 2d there.
                failIfMajorPerformanceCaveat: true,
                // attrs used by Emscripten:
                majorVersion: mode === BrowserRenderingMode.WebGL1 ? 1 : 2,
                minorVersion: 0,
                enableExtensionsByDefault: 1,
                explicitSwapControl: 0
            };

View on GitHub (pinned to 11c5427268)

Solutions

  1. Wait for the Avalonia WASM runtime 'ready'/'started' signal before creating any WebGL render target.
  2. Verify the GL interop script (the one setting globalThis.AvaloniaGL or Module.GL) is bundled and executed without errors.
  3. Supply a fallback so createRenderTarget falls through to Software2D when WebGL setup throws.
  4. Check the browser console for earlier script-load errors that prevented Module.GL assignment.

Example fix

// before
const rt = new WebGlRenderTarget(canvas, BrowserRenderingMode.WebGL2); // Module.GL not ready

// after
await runtimeReady;
if (!globalThis.Module?.GL && !globalThis.AvaloniaGL) { /* fall back to software */ }
const rt = new WebGlRenderTarget(canvas, BrowserRenderingMode.WebGL2);
Defensive patterns

Strategy: validation

Validate before calling

const gl = globalThis.Module?.GL ?? globalThis.AvaloniaGL ?? globalThis.SkiaSharpGL;
if (!gl) { /* not ready: defer or fall back to software */ }

Type guard

function hasEmscriptenGL(): boolean {
  const self = globalThis as any;
  const m = self.Module ?? self.getDotnetRuntime?.(0)?.Module;
  return !!(m?.GL ?? self.AvaloniaGL ?? self.SkiaSharpGL);
}

Try / catch

try { return new WebGlRenderTarget(canvas, mode); }
catch (e) {
  if (e instanceof Error && e.message.includes('Module.GL')) { /* fall back to Software2D */ return new SoftwareRenderTarget(canvas); }
  throw e;
}

Prevention

When it happens

Trigger: Constructing new WebGlRenderTarget(canvas, mode) before the Avalonia/SkiaSharp WASM module finished loading and set Module.GL on globalThis; the interop JS that assigns AvaloniaGL/SkiaGL failed to load (script error, wrong build artifact); running in an environment where Module is absent.

Common situations: Misordered script loading so rendering starts before the WASM bootstrapper defines Module.GL; bundler tree-shook or renamed the global assignment; dev server serving a stale build without the GL interop; SSR/prerender pass hitting rendering code with no Module.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/71ff5b3854208f74. Report an issue: GitHub.