remotion-dev/remotion · critical · Error
Failed to create WebGL shader
Error message
Failed to create WebGL shader
What it means
Thrown by gridlines' compileShader (gridlines.ts:365) when gl.createShader(type) returns null. A null return means WebGL could not allocate a shader object, typically due to context loss or severe GPU resource exhaustion. The library throws immediately because subsequent shaderSource/compileShader calls would crash on null.
Source
Thrown at packages/effects/src/gridlines.ts:365
vec4 line = uLineColor * coverage;
if (uMaskToSourceAlpha) {
fragColor = sourceAtop(sourceAtop(texColor, background), line);
return;
}
fragColor = sourceOver(sourceOver(texColor, background), line);
}
`;
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(`Gridlines shader compile failed: ${log ?? '(no log)'}`);
}
return shader;
};
const linkProgram = (
gl: WebGL2RenderingContext,
vs: WebGLShader,
fs: WebGLShader,
): WebGLProgram => {View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Check the WebGL context for loss: register a webglcontextlost listener on the canvas and recreate the effect on restore.
- Reduce the number of concurrent WebGL effects/compositions; ensure cleanup() is called so GL objects are freed.
- Restart the headless browser/GPU; if persistent, update GPU drivers or switch ANGLE backend.
- Confirm you are not creating new canvases/contexts in a render loop without disposing them.
Example fix
// before: a new effect/canvas per frame with no cleanup -> eventual null allocation
useEffect(() => { makeEffect(); }, [frame]);
// after: set up once, clean up on unmount, handle context loss
useEffect(() => {
const canvas = ref.current!;
const onLost = (e: Event) => { e.preventDefault(); /* recreate */ };
canvas.addEventListener('webglcontextlost', onLost);
const handle = setupOnce();
return () => { handle.cleanup(); canvas.removeEventListener('webglcontextlost', onLost); };
}, []); Defensive patterns
Strategy: try-catch
Validate before calling
// Probe context health before relying on GL allocation
const lost = gl.isContextLost();
if (lost) throw new Error('WebGL2 context lost before shader allocation'); Type guard
null
Try / catch
try {
gridlines.setup(canvas);
} catch (e) {
if (e instanceof Error && e.message === 'Failed to create WebGL shader') {
// context loss / resource exhaustion: recreate context, reduce load
}
throw e;
} Prevention
- Handle webglcontextlost/webglcontextrestored on the canvas.
- Always pair setup() with cleanup() to free shaders.
- Avoid creating new WebGL contexts in a render loop.
- Limit concurrent WebGL compositions on constrained GPUs.
When it happens
Trigger: Called during the Gridlines effect setup, after acquiring a WebGL2 context, for both the vertex and fragment shaders. Happens when the WebGL context is lost (e.g. GPU driver crash, too many contexts), the process has leaked GL objects, or the driver refuses new shader allocation.
Common situations: Long-running render that leaks contexts; multiple Studio previews/compositions open exhausting the GPU; a machine hitting a GPU-reset/context-loss; running on a driver/SwiftShader that caps shader count.
Related errors
- Gridlines shader compile failed: ${log ?? '(no log)'}
- Failed to create WebGL program
- Failed to create WebGL vertex array
- Failed to create WebGL buffer
- Failed to create WebGL texture
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/d1248b80db818a53.
Report an issue: GitHub.