remotion-dev/remotion · critical · Error
Failed to create WebGL shader
Error message
Failed to create WebGL shader
What it means
Thrown by halftone-linear-gradient's compileShader (halftone-linear-gradient.ts:376) when gl.createShader(type) returns null. A null shader object indicates a lost WebGL2 context or GPU resource exhaustion. The library throws because subsequent gl.shaderSource would crash on null.
Source
Thrown at packages/effects/src/halftone-linear-gradient.ts:376
uFirstStopPosition: WebGLUniformLocation | null;
uSecondStopPosition: WebGLUniformLocation | null;
uGridSize: WebGLUniformLocation | null;
uColor: WebGLUniformLocation | null;
uUseSourceColor: WebGLUniformLocation | null;
uMaskToSourceAlpha: WebGLUniformLocation | null;
colorCtx: CanvasRenderingContext2D;
cachedColorStr: string;
cachedColorRgba: ParsedColorRgba;
};
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(
`Halftone linear gradient shader compile failed: ${log ?? '(no log)'}`,
);
}
return shader;
};
const linkProgram = (
gl: WebGL2RenderingContext,
vs: WebGLShader,View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Register a webglcontextlost handler and rebuild effect state on webglcontextrestored.
- Always call cleanup() to free shaders/programs/buffers/textures.
- Reduce the number of live WebGL2 effects; render sequentially on constrained GPUs.
- Restart browser/GPU; update drivers if the failure is reproducible.
Example fix
// before: repeated setup without teardown -> eventual null allocation
useEffect(() => { halftone.setup(canvas); }, [frame]);
// after: setup once, cleanup on unmount, handle context loss
useEffect(() => {
const canvas = ref.current!;
const onLost = (e: Event) => e.preventDefault();
canvas.addEventListener('webglcontextlost', onLost);
const s = halftone.setup(canvas);
return () => { halftone.cleanup(s); canvas.removeEventListener('webglcontextlost', onLost); };
}, []); Defensive patterns
Strategy: try-catch
Validate before calling
const gl = canvas.getContext('webgl2');
if (!gl) throw new Error('WebGL2 unavailable');
if (gl.isContextLost()) throw new Error('WebGL2 context lost before shader allocation'); Type guard
null
Try / catch
try {
halftoneLinearGradient.setup(canvas);
} catch (e) {
if (e instanceof Error && e.message === 'Failed to create WebGL shader') {
// context loss / resource exhaustion: recreate, reduce load
}
throw e;
} Prevention
- Handle webglcontextlost/webglcontextrestored on the canvas.
- Always pair setup() with cleanup() to free shaders.
- Avoid creating WebGL contexts in a render loop.
- Limit concurrent WebGL compositions on constrained GPUs.
When it happens
Trigger: Called during the halftone effect setup (lines 442-447) for both the vertex and fragment shaders, right after acquiring the webgl2 context. Fires on context loss, on leaked shader objects, or when the driver's shader budget is exhausted.
Common situations: Long render leaking GL objects; many concurrent WebGL effects/compositions; GPU reset mid-render; constrained integrated GPUs or software renderers.
Related errors
- Failed to create WebGL shader
- Halftone linear gradient shader compile failed: ${log ?? '(n
- Failed to create WebGL program
- Failed to create WebGL shader
- Failed to create WebGL shader
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/4ae691fbc3463164.
Report an issue: GitHub.