remotion-dev/remotion · critical · Error
Failed to create WebGL shader
Error message
Failed to create WebGL shader
What it means
A plain Error thrown inside compileShader in the Liquid contours effect when gl.createShader(type) returns null. Identical contract to the Lines effect: WebGL2 may return null under resource exhaustion or context loss, and the effect aborts instead of dereferencing null.
Source
Thrown at packages/effects/src/liquid-contours.ts:287
float detailedField = fbm(p + warp * mix(0.35, 1.8, uComplexity));
float detailMix = smoothstep(0.0, 1.0, uComplexity);
float field = mix(roundedField, detailedField, detailMix);
float levels = max(max(uResolution.x, uResolution.y) / max(uSpacing, 0.001), 1.0);
float wave = sin((field * levels + uPhase) * 6.28318530718);
float edgeWidth = fwidth(wave) * mix(0.15, 1.4, uSmoothness);
float selector = smoothstep(-edgeWidth, edgeWidth, wave);
vec4 color = mix(uFirstColor, uSecondColor, selector);
fragColor = vec4(color.rgb * color.a, color.a);
}
`;
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(
`Liquid contours shader compile failed: ${log ?? '(no log)'}`,
);
}
return shader;
};
const createProgram = (gl: WebGL2RenderingContext): WebGLProgram => {
const vs = compileShader(gl, gl.VERTEX_SHADER, VERTEX_SHADER);
const fs = compileShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER);
const program = gl.createProgram();
if (!program) throw new Error('Failed to create WebGL program');View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Reduce concurrent browser contexts / render parallelism.
- Confirm the host WebGL2 stack is healthy with a smoke test.
- Handle webglcontextlost / webglcontextrestored and re-instantiate the effect.
Defensive patterns
Strategy: try-catch
Validate before calling
function webgl2Ready(): boolean {
const c = document.createElement('canvas');
const gl = c.getContext('webgl2');
const ok = !!gl && !!gl.createShader(gl.VERTEX_SHADER);
return ok;
} Try / catch
try {
liquidContours(...);
} catch (err) {
if (err instanceof Error && /WebGL shader/.test(err.message)) {
// fall back or surface 'GPU unavailable'
} else throw err;
} Prevention
- Smoke-test gl.createShader on the target browser before rendering.
- Cap concurrent render contexts to keep GPU shader objects available.
- Use a known-good GL backend for headless Chrome.
When it happens
Trigger: The WebGL2 context exists (passed the earlier createWebGL2ContextError check for 'liquid contours effect') but cannot allocate a shader object. GPU memory exhaustion, too many live shaders, or a lost context.
Common situations: Many concurrent Remotion renders; a page that leaked GL objects; headless software GL with a small budget; transient context-loss during a long render.
Related errors
- Failed to create WebGL shader
- Failed to create WebGL program
- Failed to create WebGL program
- Failed to create WebGL vertex array
- Failed to create WebGL buffer
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/d01a6a566ca52ec2.
Report an issue: GitHub.