a-b-street/abstreet · critical
{}
Error message
{} What it means
widgetry panics when a WebGL shader program fails to link. The library attaches the compiled shaders, calls link_program, and checks get_program_link_status; on failure it logs and panics with the driver's info log. This means a vertex/fragment shader failed to compile or link (varying mismatch, uniform type conflicts, unsupported GLSL).
Solutions
- Read the panic message: it contains gl.get_program_info_log with the driver's exact link error.
- Check the error! log line emitted just before the panic for the same info log.
- Diff varying/attribute names and types between the vertex and fragment shaders; they must match exactly in WebGL1.
- Test the shaders on the failing target (browser/GPU) — a program linking on desktop GL may fail on WebGL1/ANGLE.
- Reduce uniform/attribute count if the log reports resource limits exceeded.
Example fix
// before varying vec3 pos; // fragment shader // after varying vec3 world_pos; // matching name and type in BOTH vertex and fragment shaders
Defensive patterns
Strategy: validation
Validate before calling
// Compile each stage first and check status before linking
assert!(gl.get_shader_compile_status(vs), "vs: {}", gl.get_shader_info_log(vs));
assert!(gl.get_shader_compile_status(fs), "fs: {}", gl.get_shader_info_log(fs)); Try / catch
// Not catchable in Rust: this is a panic. Validate shader pairs before shipping; in release, wrap startup in catch_unwind to surface the info log.
Prevention
- Log shader info logs at compile time, not just link time
- Keep varying names/types identical between vertex and fragment stages
- Test shaders on WebGL1 and WebGL2 targets and multiple GPUs
- Keep uniform count within conservative limits
When it happens
Trigger: Calling setup/webgl1_program/webgl2_program with shader source that compiles individually but fails to link: mismatched varyings between vertex and fragment stages, uniform declared with different types across stages, too many uniforms for the GPU, or GLSL syntax the driver rejects.
Common situations: Running on drivers/ANGLE backends with stricter linking rules, upgrading GPU drivers changing GLSL validation, hand-edited shader strings with typos in varying names, using GLSL features unsupported by WebGL1 (e.g. dynamic loop bounds).
Related errors
- error creating texture
- This build of A/B Street stores player data in…
- Can't find the data/ directory
- CityName::new( , ) has a country code that isn't two letters
- Couldn't read_json( )
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/4d609f65dd4b71bc.
Report an issue: GitHub.
Appendix: source
Thrown at widgetry/src/backend_glow.rs:34
gl: &glow::Context,
vertex_shader_src: &str,
fragment_shader_src: &str,
) -> anyhow::Result<glow::Program> {
let program = gl.create_program().expect("Cannot create program");
let shaders = [
compile_shader(gl, glow::VERTEX_SHADER, vertex_shader_src)?,
compile_shader(gl, glow::FRAGMENT_SHADER, fragment_shader_src)?,
];
for shader in &shaders {
gl.attach_shader(program, *shader);
}
gl.link_program(program);
if !gl.get_program_link_status(program) {
error!("Linking error: {}", gl.get_program_info_log(program));
panic!("{}", gl.get_program_info_log(program));
}
for shader in &shaders {
gl.detach_shader(program, *shader);
gl.delete_shader(*shader);
}
gl.use_program(Some(program));
gl.enable(glow::SCISSOR_TEST);
gl.enable(glow::DEPTH_TEST);
gl.depth_func(glow::LEQUAL);
gl.enable(glow::BLEND);
gl.blend_func_separate(
glow::ONE,
glow::ONE_MINUS_SRC_ALPHA,
glow::ONE_MINUS_DST_ALPHA,
glow::ONE,View on GitHub (pinned to 0964f29315)