a-b-street/abstreet · critical · anyhow::Error
Browser doesn't support WebGL 1.0
Error message
Browser doesn't support WebGL 1.0
What it means
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.
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
Example fix
// before: blindly requesting webgl
let ctx = webgl1_glow_context(&canvas)?;
// after: probe first and fail with a clear message
let supported = js_sys::eval("document.createElement('canvas').getContext('webgl') != null").unwrap().as_bool().unwrap_or(false);
anyhow::ensure!(supported, "WebGL 1.0 unavailable; enable hardware acceleration");
let ctx = webgl1_glow_context(&canvas)?; Defensive patterns
Strategy: fallback
Validate before calling
let supported = web_sys::window().unwrap().navigator().user_agent().map(|ua| ua.contains("HeadlessChrome")).unwrap_or(false) == false;
let probe = js_sys::eval("!!document.createElement('canvas').getContext('webgl')").unwrap().as_bool().unwrap_or(false);
if !probe { show_no_webgl_message(); return; } Type guard
function webgl_supported(): boolean {
try { const c = document.createElement('canvas'); return !!(c.getContext('webgl') || c.getContext('experimental-webgl')); } catch { return false; }
} Try / catch
match webgl1_glow_context(&canvas) {
Ok(gl) => start(gl),
Err(e) => { render_error_page("This app requires WebGL 1.0. Enable hardware acceleration."); }
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
Related errors
- error getting context for WebGL 2.0
- error getting context for WebGL 1.0
- no window?
- local_storage failed
- no local_storage?
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/3bee49aaa4f0276c.
Report an issue: GitHub.
Appendix: source
Thrown at widgetry/src/backend_glow_wasm.rs:99
fn webgl2_glow_context(canvas: &web_sys::HtmlCanvasElement) -> Result<glow::Context> {
let maybe_context: Option<_> = canvas
.get_context("webgl2")
.map_err(|err| anyhow!("error getting context for WebGL 2.0: {:?}", err))?;
let js_webgl2_context =
maybe_context.ok_or(anyhow!("Browser doesn't support WebGL 2.0"))?;
let webgl2_context = js_webgl2_context
.dyn_into::<web_sys::WebGl2RenderingContext>()
.map_err(|err| anyhow!("unable to cast to WebGl2RenderingContext. error: {:?}", err))?;
Ok(glow::Context::from_webgl2_context(webgl2_context))
}
fn webgl1_glow_context(canvas: &web_sys::HtmlCanvasElement) -> Result<glow::Context> {
let maybe_context: Option<_> = canvas
.get_context("webgl")
.map_err(|err| anyhow!("error getting context for WebGL 1.0: {:?}", err))?;
let js_webgl1_context =
maybe_context.ok_or(anyhow!("Browser doesn't support WebGL 1.0"))?;
let webgl1_context = js_webgl1_context
.dyn_into::<web_sys::WebGlRenderingContext>()
.map_err(|err| anyhow!("unable to cast to WebGlRenderingContext. error: {:?}", err))?;
Ok(glow::Context::from_webgl1_context(webgl1_context))
}
(
PrerenderInnards::new(gl, is_gl2, program, Some(WindowAdapter(winit_window))),
event_loop,
)
}
fn webgl2_program(gl: glow::Context) -> Result<(glow::Context, glow::Program)> {
let program = unsafe {
build_program(
&gl,
include_str!("../shaders/vertex_300.glsl"),
include_str!("../shaders/fragment_300.glsl"),View on GitHub (pinned to 0964f29315)