pbakaus/impeccable · warning

[impeccable] shader bitmap decode failed:

Error message

[impeccable] shader bitmap decode failed:

What it means

After the shader overlay's GL setup succeeds, the captured screenshot blob is decoded with createImageBitmap before texture upload. If decoding rejects — empty/corrupt blob from a racing capture, decode OOM, browser quirk — the code logs 'shader bitmap decode failed:', force-loses the WebGL context via WEBGL_lose_context, and shows showShaderBitmapFallback: a static, non-GL rendering of the same image.

Source

Thrown at skill/scripts/live-browser.js:8402

      ]), gl.STATIC_DRAW);
      const posLoc = gl.getAttribLocation(program, 'a_position');
      const uvLoc = gl.getAttribLocation(program, 'a_uv');
      gl.enableVertexAttribArray(posLoc);
      gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 16, 0);
      gl.enableVertexAttribArray(uvLoc);
      gl.vertexAttribPointer(uvLoc, 2, gl.FLOAT, false, 16, 8);
    } catch (err) {
      console.warn('[impeccable] shader setup failed:', err);
      canvas.remove();
      return;
    }

    // Upload the screenshot as a texture
    let bitmap;
    try {
      bitmap = await createImageBitmap(blob);
    } catch (err) {
      console.warn('[impeccable] shader bitmap decode failed:', err);
      const lose = gl.getExtension?.('WEBGL_lose_context');
      try { lose?.loseContext(); } catch {}
      showShaderBitmapFallback(canvas, blob);
      return;
    }
    texture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, bitmap);
    if (bitmap.close) bitmap.close();

    const uTime = gl.getUniformLocation(program, 'u_time');
    const uRes = gl.getUniformLocation(program, 'u_resolution');
    const uAccent = gl.getUniformLocation(program, 'u_accent');

View on GitHub (pinned to f88b2837a7)

Solutions

  1. No action needed — the static fallback shows the same screenshot
  2. If this recurs, chase the upstream capture path (a decode failure usually means the blob was never valid)
  3. Retry the generate to get a fresh capture and a working animated overlay
Defensive patterns

Strategy: fallback

Validate before calling

if (!blob || blob.size === 0) { showShaderBitmapFallback(canvas, blob); return; } // skip decode for empty blobs

Try / catch

try { bitmap = await createImageBitmap(blob); } catch (err) { console.warn(err); gl.getExtension?.('WEBGL_lose_context')?.loseContext(); showShaderBitmapFallback(canvas, blob); return; }

Prevention

When it happens

Trigger: The blob passed in is empty or truncated because capture raced DOM teardown (see the capture-failed path); image decode under memory pressure; browsers with partial createImageBitmap support for PNG blobs.

Common situations: See trigger scenarios.

Related errors


AI-assisted analysis of pbakaus/impeccable@f88b2837a7 (2026-08-18). Data as JSON: /api/errors/9fa009f105131619. Report an issue: GitHub.