remotion-dev/remotion · error · Error
Failed to create WebGL shader
Error message
Failed to create WebGL shader
What it means
Thrown by compileShader in pixelate.ts when gl.createShader() returns null. The shader object is the first thing needed to compile GLSL, and a null return means the GL implementation cannot allocate another shader — almost always because the context is lost or has hit an internal shader-object cap. The guard prevents shaderSource/compileShader from receiving null.
Source
Thrown at packages/effects/src/pixelate.ts:87
uniform sampler2D uSource;
uniform float uBlockSize;
uniform vec2 uResolution;
void main() {
vec2 pixelSizeUv = vec2(uBlockSize) / uResolution;
vec2 blockUv = floor(vUv / pixelSizeUv) * pixelSizeUv + pixelSizeUv * 0.5;
fragColor = texture(uSource, blockUv);
}
`;
const compileShader = (
gl: WebGL2RenderingContext,
type: number,
source: string,
): WebGLShader => {
const shader = gl.createShader(type);
if (!shader) {
throw new Error('Failed to create WebGL shader');
}
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const log = gl.getShaderInfoLog(shader);
gl.deleteShader(shader);
throw new Error(`Pixelate shader compile failed: ${log ?? '(no log)'}`);
}
return shader;
};
const linkProgram = (
gl: WebGL2RenderingContext,
vs: WebGLShader,
fs: WebGLShader,
): WebGLProgram => {View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Confirm WebGL2 is functional with a probe: `const gl=canvas.getContext('webgl2'); const s=gl && gl.createShader(gl.VERTEX_SHADER);` — if s is null, the environment is the cause.
- On Remotion Lambda use the published Chrome layer with SwiftShader enabled; do not run with --disable-gpu without --use-gl=swiftshader.
- Reduce the number of distinct WebGL2 effects mounted concurrently; each pixelate instance compiles two shaders.
- Listen for 'webglcontextlost' on the canvas and remount the effect when 'webglcontextrestored' fires.
- Update the GPU driver if reproducing on a single physical machine.
Example fix
// before
import {pixelate} from '@remotion/effects';
const effect = pixelate();
// after — detect before mounting
function webgl2CanCompileShader(): boolean {
const c = document.createElement('canvas');
const gl = c.getContext('webgl2');
if (!gl) return false;
const s = gl.createShader(gl.VERTEX_SHADER);
if (s) gl.deleteShader(s);
return s !== null;
} Defensive patterns
Strategy: try-catch
Validate before calling
function glCanCreateShader(gl: WebGL2RenderingContext): boolean {
if (gl.isContextLost()) return false;
const s = gl.createShader(gl.VERTEX_SHADER);
if (s) gl.deleteShader(s);
return s !== null;
} Try / catch
try {
pixelate();
} catch (err) {
if (/Failed to create WebGL shader/.test((err as Error).message)) {
// report WebGL2 unavailable; fall back to a non-GPU effect
}
throw err;
} Prevention
- Feature-detect shader allocation in headless/CI environments before rendering.
- On Lambda use the bundled Chrome for Testing layer.
- Handle context-loss events and remount effects on restore.
- Limit concurrent WebGL2 effects to keep shader-object count under driver caps.
When it happens
Trigger: pixelate() setup calls compileShader for the vertex shader (or fragment shader); gl.createShader(type) returns null. No GLSL has been compiled yet at this point, so the failure is purely about GL object allocation, not source correctness.
Common situations: Headless Chrome without GPU (SwiftShader); context lost between frames; many WebGL2 effects each allocating their own shaders in one tab; driver that caps total shader objects; environment that returned a WebGL2 context object but cannot actually service it (some virtualized GPU setups).
Related errors
- Failed to create WebGL shader
- Failed to create WebGL shader
- Failed to create WebGL vertex array
- Failed to create WebGL program
- Failed to create WebGL vertex array
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/75a25fb77163f269.
Report an issue: GitHub.