remotion-dev/remotion · error · Error
Failed to create WebGL program
Error message
Failed to create WebGL program
What it means
The skew() effect acquired a WebGL2 context and compiled both shaders, but gl.createProgram() returned null in setupSkew(). A null program object means the context lost resources or hit a driver-imposed program limit, so the effect cannot link its vertex/fragment shaders and throws before continuing.
Source
Thrown at packages/effects/src/skew.ts:193
return shader;
};
const setupSkew = (target: HTMLCanvasElement): SkewState => {
const gl = target.getContext('webgl2', {
premultipliedAlpha: true,
alpha: true,
preserveDrawingBuffer: true,
});
if (!gl) {
throw createWebGL2ContextError('skew effect');
}
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
const vertexShader = compileShader(gl, gl.VERTEX_SHADER, SKEW_VS);
const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, SKEW_FS);
const program = gl.createProgram();
if (!program) {
throw new Error('Failed to create WebGL program');
}
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.deleteShader(vertexShader);
gl.deleteShader(fragmentShader);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
const log = gl.getProgramInfoLog(program);
gl.deleteProgram(program);
throw new Error(`Skew program link failed: ${log ?? '(no log)'}`);
}
const vao = gl.createVertexArray();
const vbo = gl.createBuffer();
if (!vao || !vbo) {
throw new Error('Failed to create WebGL geometry');
}View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Use the ANGLE backend (--gl=angle / chromiumOptions.gl='angle' / Studio OpenGL=angle) for more reliable program allocation.
- Reduce concurrency and the count of simultaneously-active WebGL2 effects to stay under driver resource limits.
- Ensure effect cleanup (gl.deleteProgram etc.) runs so program handles are freed before new effects allocate them.
- Render on a host with a supported GPU and up-to-date drivers.
Example fix
// before
await renderMedia({ composition, serveUrl });
// after
await renderMedia({ composition, serveUrl, chromiumOptions: { gl: 'angle' } }); Defensive patterns
Strategy: try-catch
Validate before calling
// No caller-side check can predict a null gl.createProgram().
// Best pre-flight is generic WebGL2 capability (see error 900).
function webgl2Available(): boolean {
try {
return !!document.createElement('canvas').getContext('webgl2');
} catch {
return false;
}
} Try / catch
try {
await renderMedia({ composition, codec: 'h264', chromiumOptions: { gl: 'angle' } });
} catch (err) {
if (err instanceof Error && /Failed to create WebGL program/.test(err.message)) {
console.error('skew() could not allocate a WebGL program (context lost/exhausted). Lower concurrency or switch GL backend.', err);
throw err;
}
throw err;
} Prevention
- Render WebGL2 effects with ANGLE and conservative concurrency.
- Free effect resources (cleanup) before allocating new ones.
- Monitor for WebGL context-loss events in long-running renders.
- Render on hosts with verified GPU/driver support.
When it happens
Trigger: Context loss or GPU resource exhaustion occurring between shader compilation and program creation inside setupSkew(); a driver that imposes a low ceiling on simultaneously-live program objects when many WebGL2 effects are initialized.
Common situations: Many stacked WebGL2 effects per composition combined with high render concurrency; long-running renders that gradually exhaust driver resources; headless/CI hosts without a real GPU; driver reset mid-setup.
Related errors
- Failed to create WebGL shader
- Failed to create WebGL buffer
- Failed to create WebGL geometry
- Failed to create WebGL texture
- Failed to create WebGL shader
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/11d7e4b225bb5c0d.
Report an issue: GitHub.