remotion-dev/remotion · error · Error

Failed to create WebGL shader

Error message

Failed to create WebGL shader

What it means

The outline() effect of @remotion/effects sets up a WebGL2 pipeline on the render target. compileShader() calls gl.createShader(), which the WebGL spec allows to return null only when the context is lost or invalid - so this error means the WebGL2 context acquired moments earlier is no longer usable. createShader is the first GL object allocation in the outline setup, so it is typically the first call to fail after a context loss.

Source

Thrown at packages/effects/src/outline.ts:229

		) * uColor.a * uOpacity;
		fragColor = vec4(uColor.rgb * filledAlpha, filledAlpha);
		return;
	}

	float outlineAlpha = outlineMaskAlpha * uColor.a * uOpacity * (1.0 - source.a);
	vec3 outlineRgb = uColor.rgb * outlineAlpha;
	fragColor = vec4(source.rgb + outlineRgb, source.a + outlineAlpha);
}
`;

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(`Outline shader compile failed: ${log ?? '(no log)'}`);
	}

	return shader;
};

const createProgram = (gl: WebGL2RenderingContext): WebGLProgram => {
	const vertexShader = compileShader(gl, gl.VERTEX_SHADER, OUTLINE_VS);
	const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, OUTLINE_FS);
	const program = gl.createProgram();
	if (!program) {

View on GitHub (pinned to 10db9de073)

Solutions

  1. Re-run the render or reload Remotion Studio - a transient context loss usually clears on a fresh page
  2. Lower render concurrency (e.g. --concurrency=2 in the CLI or concurrency option in renderMediaOnLambda) so fewer WebGL contexts are alive at once
  3. Update Chrome/Chromium and GPU drivers, or run the renderer on a machine/driver combination where WebGL2 is stable
  4. If it reproduces deterministically on one frame, file an @remotion/effects issue with the Chrome version and the composition
Defensive patterns

Strategy: retry

Validate before calling

// Before a render that relies on WebGL2 effects, verify a context can be created
const webgl2Available = (): boolean => {
  try {
    const canvas = document.createElement('canvas');
    const gl = canvas.getContext('webgl2');
    return gl !== null;
  } catch {
    return false;
  }
};

Try / catch

// Retry once: context loss is usually transient
try {
  await renderMediaOnLambda(/* ... */); // or renderMedia in @remotion/renderer
} catch (err) {
  if (err instanceof Error && err.message.includes('Failed to create WebGL shader')) {
    await renderMediaOnLambda(/* ... same args */);
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Applying the outline() effect when the WebGL2 context is lost or exhausted: GPU driver reset, too many live WebGL contexts in one Chrome instance (high --concurrency rendering many effect-heavy frames), or memory pressure during a long render.

Common situations: Rendering on headless Chrome with GPU/SwiftShader instability; rendering many pages in parallel each using outline() so the browser hits its per-profile WebGL context cap; machines with outdated or crashed GPU drivers; long Lambda renders under memory pressure.

Related errors


AI-assisted analysis of remotion-dev/remotion@10db9de073 (2026-08-22). Data as JSON: /api/errors/d8c25695b40832cd. Report an issue: GitHub.