a-b-street/abstreet · error · anyhow::Error
unable to cast to WebGlRenderingContext. error
Error message
unable to cast to WebGlRenderingContext. error: {:?} What it means
After obtaining a context object from get_context, the code dyn_into::<WebGlRenderingContext>() casts it to the WebGL 1.0 type. The cast failed, meaning the object returned by the browser is not a WebGL 1.0 rendering context (e.g. it is a WebGL2 context or another type). The library throws because glow was asked for a WebGL1-backed context but got a different JS object.
Solutions
- Only create one context per canvas; do not request 'webgl2' before calling this
- Create a fresh canvas element for the WebGL 1.0 context
- Check that no graphics library (three.js, regl, etc.) initialized the canvas first
- Log js_sys::Object::to_string on the returned value to see the actual type
Example fix
// before: reuse canvas that may already have a webgl2 context
let ctx = webgl1_glow_context(&existing_canvas)?;
// after: use a dedicated canvas
let canvas = document.create_element("canvas").unwrap().dyn_into::<web_sys::HtmlCanvasElement>().unwrap();
let ctx = webgl1_glow_context(&canvas)?; Defensive patterns
Strategy: type-guard
Validate before calling
let kind = canvas.get_context("webgl").ok().flatten().map(|v| js_sys::Object::from(v).to_string().into());
log::info!("context type: {:?}", kind); // should be [object WebGLRenderingContext] Type guard
fn is_webgl1(val: &wasm_bindgen::JsValue) -> bool {
val.is_instance_of::<web_sys::WebGlRenderingContext>()
} Try / catch
match canvas.get_context("webgl") {
Ok(Some(v)) if v.is_instance_of::<WebGlRenderingContext>() => { /* proceed */ }
Ok(Some(v)) => error!("unexpected context type: {:?}", v.js_typeof()),
_ => error!("no webgl context"),
} Prevention
- Create exactly one context per canvas; never request webgl2 first
- Initialize your graphics context before any other library touches the canvas
- Use a dedicated, freshly created canvas element
When it happens
Trigger: canvas.get_context("webgl") returned a non-null object whose runtime type is not WebGlRenderingContext — typically because a 'webgl2' context was previously created on the same canvas, or a nonstandard/incorrect object was returned.
Common situations: Mixing WebGL2 and WebGL1 initialization on the same canvas (browsers return the existing context type), custom canvas wrappers or frameworks (e.g. three.js) that already grabbed the context, stale/shimmed polyfills.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- error getting context for WebGL 2.0
- Browser doesn't support WebGL 2.0
- unable to cast to WebGl2RenderingContext. error
- error getting context for WebGL 1.0
- Browser doesn't support WebGL 1.0
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/90fdb8a728b6a8c6.
Report an issue: GitHub.
Appendix: source
Thrown at widgetry/src/backend_glow_wasm.rs:102
.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"),
)?
};
Ok((gl, program))View on GitHub (pinned to 0964f29315)