{"record":{"id":"3bee49aaa4f0276c","repo":"a-b-street/abstreet","slug":"browser-doesn-t-support-webgl-1-0","errorCode":null,"errorMessage":"Browser doesn't support WebGL 1.0","messagePattern":"Browser doesn't support WebGL 1\\.0","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"widgetry/src/backend_glow_wasm.rs","lineNumber":99,"sourceCode":"\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))\n    }\n\n    (\n        PrerenderInnards::new(gl, is_gl2, program, Some(WindowAdapter(winit_window))),\n        event_loop,\n    )\n}\n\nfn webgl2_program(gl: glow::Context) -> Result<(glow::Context, glow::Program)> {\n    let program = unsafe {\n        build_program(\n            &gl,\n            include_str!(\"../shaders/vertex_300.glsl\"),\n            include_str!(\"../shaders/fragment_300.glsl\"),","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/widgetry/src/backend_glow_wasm.rs#L81-L117","documentation":"webgl1_glow_context requests a 'webgl' (WebGL 1.0) context from the HTML canvas via get_context. The browser returned Ok(None), meaning it could not supply a WebGL 1.0 context for this canvas. The library throws this because glow needs a valid WebGL context to render at all; there is no software fallback.","triggerScenarios":"canvas.get_context(\"webgl\") returns None in a wasm browser build: the browser lacks WebGL 1.0 support or WebGL is disabled, the canvas already has a different context type bound, or GPU/driver contexts are exhausted.","commonSituations":"Running in a headless browser or CI environment without GPU, WebGL disabled via browser flags/policy, browser fallback paths that only implement WebGL2 or no WebGL at all, or the canvas already initialized with a 'webgl2' or '2d' context.","solutions":["Enable WebGL in the browser (chrome://flags / browser settings, hardware acceleration on)","Test in a normal (non-headless) browser with GPU access","Ensure the canvas has no other context type already created on it","Use a browser or device known to support WebGL 1.0; consider a WebGL2 fallback path in setup"],"exampleFix":"// before: blindly requesting webgl\nlet ctx = webgl1_glow_context(&canvas)?;\n// after: probe first and fail with a clear message\nlet supported = js_sys::eval(\"document.createElement('canvas').getContext('webgl') != null\").unwrap().as_bool().unwrap_or(false);\nanyhow::ensure!(supported, \"WebGL 1.0 unavailable; enable hardware acceleration\");\nlet ctx = webgl1_glow_context(&canvas)?;","handlingStrategy":"fallback","validationCode":"let supported = web_sys::window().unwrap().navigator().user_agent().map(|ua| ua.contains(\"HeadlessChrome\")).unwrap_or(false) == false;\nlet probe = js_sys::eval(\"!!document.createElement('canvas').getContext('webgl')\").unwrap().as_bool().unwrap_or(false);\nif !probe { show_no_webgl_message(); return; }","typeGuard":"function webgl_supported(): boolean {\n  try { const c = document.createElement('canvas'); return !!(c.getContext('webgl') || c.getContext('experimental-webgl')); } catch { return false; }\n}","tryCatchPattern":"match webgl1_glow_context(&canvas) {\n    Ok(gl) => start(gl),\n    Err(e) => { render_error_page(\"This app requires WebGL 1.0. Enable hardware acceleration.\"); }\n}","preventionTips":["Probe for WebGL support before launching the app and show a friendly message","Warn if running in headless/CI environments without GPU","Never mix webgl and webgl2 context requests on the same canvas","Keep hardware acceleration enabled in test browsers"],"tags":["wasm","webgl","browser","graphics-init"],"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"}