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
- No action needed — the static fallback shows the same screenshot
- If this recurs, chase the upstream capture path (a decode failure usually means the blob was never valid)
- 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
- Validate the blob exists and is non-empty before decoding
- Investigate recurring decode failures upstream — they usually trace to a racing capture
- Keep the static fallback path tested so degrade-to-image is always available
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.