{"record":{"id":"75bac1df90bf9c74","repo":"a-b-street/abstreet","slug":"error-getting-context-for-webgl-2-0","errorCode":null,"errorMessage":"error getting context for WebGL 2.0: {:?}","messagePattern":"error getting context for WebGL 2\\.0: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"widgetry/src/backend_glow_wasm.rs","lineNumber":85,"sourceCode":"    let mut is_gl2 = true;\n    let (gl, program) = webgl2_glow_context(&canvas)\n        .and_then(|gl| webgl2_program(gl))\n        .or_else(|err| {\n            warn!(\n                \"failed to build WebGL 2.0 context with error: \\\"{}\\\". Trying WebGL 1.0 instead...\",\n                err\n            );\n            webgl1_glow_context(&canvas).and_then(|gl| {\n                is_gl2 = false;\n                webgl1_program(gl)\n            })\n        })\n        .unwrap();\n\n    fn webgl2_glow_context(canvas: &web_sys::HtmlCanvasElement) -> Result<glow::Context> {\n        let maybe_context: Option<_> = canvas\n            .get_context(\"webgl2\")\n            .map_err(|err| anyhow!(\"error getting context for WebGL 2.0: {:?}\", err))?;\n        let js_webgl2_context =\n            maybe_context.ok_or(anyhow!(\"Browser doesn't support WebGL 2.0\"))?;\n        let webgl2_context = js_webgl2_context\n            .dyn_into::<web_sys::WebGl2RenderingContext>()\n            .map_err(|err| anyhow!(\"unable to cast to WebGl2RenderingContext. error: {:?}\", err))?;\n        Ok(glow::Context::from_webgl2_context(webgl2_context))\n    }\n\n    fn webgl1_glow_context(canvas: &web_sys::HtmlCanvasElement) -> Result<glow::Context> {\n        let maybe_context: Option<_> = canvas\n            .get_context(\"webgl\")\n            .map_err(|err| anyhow!(\"error getting context for WebGL 1.0: {:?}\", err))?;\n        let js_webgl1_context =\n            maybe_context.ok_or(anyhow!(\"Browser doesn't support WebGL 1.0\"))?;\n        let webgl1_context = js_webgl1_context\n            .dyn_into::<web_sys::WebGlRenderingContext>()\n            .map_err(|err| anyhow!(\"unable to cast to WebGlRenderingContext. error: {:?}\", err))?;\n        Ok(glow::Context::from_webgl1_context(webgl1_context))","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/widgetry/src/backend_glow_wasm.rs#L67-L103","documentation":"webgl2_glow_context requests a \"webgl2\" context from the canvas via get_context. If the browser API call itself errors (a JsValue failure rather than simply returning null), it is wrapped as this error. It is distinct from the browser merely not supporting WebGL 2 (that produces a separate message).","triggerScenarios":"setup() on wasm calls webgl2_glow_context and canvas.get_context(\"webgl2\") rejects — e.g., cross-origin tainted canvases, privacy settings blocking WebGL, or JS exceptions in the binding call.","commonSituations":"Browsers with WebGL disabled via flags or privacy extensions; canvas already bound to a different context type; corporate policies or headless environments blocking GPU access.","solutions":["Enable WebGL (and specifically WebGL 2) in browser settings or privacy extensions.","Ensure the canvas isn't already acquired with another context type (e.g., 2d) before requesting webgl2.","Rely on setup's fallback: it should try webgl2 then webgl1; verify the fallback path executes.","Test in a different browser/driver to isolate environment-specific getContext failures."],"exampleFix":"// before\nlet maybe_context: Option<_> = canvas\n    .get_context(\"webgl2\")\n    .map_err(|err| anyhow!(\"error getting context for WebGL 2.0: {:?}\", err))?;\n// after: caller handles fallback\nlet ctx = match webgl2_glow_context(canvas) {\n    Ok(c) => c,\n    Err(_) => webgl1_glow_context(canvas)?, // graceful degradation\n};","handlingStrategy":"fallback","validationCode":"// Feature-detect WebGL 2 before requesting it\nconst hasWebGL2 = (() => {\n  const c = document.createElement('canvas');\n  return !!(c.getContext('webgl2'));\n})();","typeGuard":null,"tryCatchPattern":"// Try webgl2, then webgl1, then surface a clear message\nlet ctx = webgl2_glow_context(canvas)\n    .or_else(|_| webgl1_glow_context(canvas))\n    .map_err(|e| anyhow!(\"No usable WebGL context: {}\", e))?;","preventionTips":["Feature-detect WebGL 2 before setup and choose the GL path up front","Never acquire a 2d context on the same canvas used for WebGL","Document browser requirements (WebGL 2) for users","Handle webglcontextlost/restored events in the app"],"tags":["webgl","wasm","browser","rendering"],"backgroundTag":"unsupported-platform","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}