{"record":{"id":"ec14e0fbbe61d3a0","repo":"AvaloniaUI/Avalonia","slug":"htmlcanvaselement-getcontext-returned-null","errorCode":null,"errorMessage":"HTMLCanvasElement.getContext returned null.","messagePattern":"HTMLCanvasElement\\.getContext returned null\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Browser/Avalonia.Browser/webapp/modules/avalonia/rendering/webGlRenderTarget.ts","lineNumber":56,"sourceCode":"                depth: true,\n                stencil: true,\n                antialias: false,\n                premultipliedAlpha: true,\n                preserveDrawingBuffer: false,\n                // only supported on older browsers, which is perfect as we want to fallback to 2d there.\n                failIfMajorPerformanceCaveat: true,\n                // attrs used by Emscripten:\n                majorVersion: mode === BrowserRenderingMode.WebGL1 ? 1 : 2,\n                minorVersion: 0,\n                enableExtensionsByDefault: 1,\n                explicitSwapControl: 0\n            };\n\n        const context = (mode === BrowserRenderingMode.WebGL1\n            ? canvas.getContext(\"webgl\", attrs)\n            : canvas.getContext(\"webgl2\", attrs)) as WebGLRenderingContext;\n        if (!context) {\n            throw new Error(\"HTMLCanvasElement.getContext returned null.\");\n        }\n\n        const handle = WebGlRenderTarget._gl.registerContext(context, attrs);\n        (context as any).gl_handle = handle;\n        super(canvas, \"webgl\");\n\n        this.contextHandle = handle;\n        this.fboId = context.getParameter(context.FRAMEBUFFER_BINDING)?.id ?? 0;\n        this.stencil = context.getParameter(context.STENCIL_BITS);\n        this.sample = context.getParameter(context.SAMPLES);\n        this.depth = context.getParameter(context.DEPTH_BITS);\n        this.attrs = attrs;\n    }\n\n    public static getCurrentContext(): number {\n        return WebGlRenderTarget._gl?.currentContext?.handle ?? 0;\n    }\n","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Browser/Avalonia.Browser/webapp/modules/avalonia/rendering/webGlRenderTarget.ts#L38-L74","documentation":"Thrown by the WebGlRenderTarget constructor when canvas.getContext('webgl'/'webgl2') returns null. The request uses failIfMajorPerformanceCaveat:true, so a context backed only by a software rasterizer is deliberately rejected, and a genuine null means the browser declined to create a WebGL context.","triggerScenarios":"Requesting a 'webgl2' context on a browser/device that only supports WebGL1; a canvas already bound to a 2D context; the device uses a software WebGL implementation (blocked by failIfMajorPerformanceCaveat); WebGL disabled in the browser; the canvas was consumed by transferControlToOffscreen on the main thread.","commonSituations":"Older/mobile browsers without WebGL2; headless CI browsers with no GPU; user disabled hardware acceleration; failIfMajorPerformanceCaveat rejecting a SwiftShader fallback; reusing a canvas that already got a 2D context for software rendering.","solutions":["List WebGL1 before WebGL2 in preferredModes so browsers without WebGL2 can fall back.","Keep Software2D as the last preferred mode so createRenderTarget can recover.","Ensure the canvas given to WebGL has not already acquired a 2D context and was not transferred offscreen.","For headless tests, launch the browser with software WebGL flags or supply a WebGL polyfill."],"exampleFix":"// before\npreferredModes = [BrowserRenderingMode.WebGL2, BrowserRenderingMode.WebGL1]\n// -> WebGL2 null on an older device throws and aborts\n\n// after\npreferredModes = [BrowserRenderingMode.WebGL2, BrowserRenderingMode.WebGL1, BrowserRenderingMode.Software2D]","handlingStrategy":"fallback","validationCode":"function supportsMode(mode: BrowserRenderingMode, canvas: HTMLCanvasElement | OffscreenCanvas): boolean {\n  const t = mode === BrowserRenderingMode.WebGL1 ? 'webgl' : 'webgl2';\n  return canvas.getContext(t) != null; // note: probe only; do not consume in production\n}","typeGuard":"function hasWebGL2(canvas: HTMLCanvasElement | OffscreenCanvas): boolean {\n  return canvas.getContext('webgl2') != null;\n}","tryCatchPattern":"try { return new WebGlRenderTarget(canvas, mode); }\ncatch (e) {\n  if (e instanceof Error && /getContext/.test(e.message)) { /* try next preferred mode */ }\n  throw e;\n}","preventionTips":["Order preferredModes [WebGL2, WebGL1, Software2D].","Do not reuse a canvas that already has a 2D context for WebGL.","In headless CI, enable software-WebGL or rely on Software2D."],"tags":["browser","rendering","webgl","canvas","typescript","fallback"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}