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

  1. Read the panic message: it contains gl.get_program_info_log with the driver's exact link error.
  2. Check the error! log line emitted just before the panic for the same info log.
  3. Diff varying/attribute names and types between the vertex and fragment shaders; they must match exactly in WebGL1.
  4. Test the shaders on the failing target (browser/GPU) — a program linking on desktop GL may fail on WebGL1/ANGLE.
  5. 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

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


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)