remotion-dev/remotion · error · Error
Failed to create shader
Error message
Failed to create shader
What it means
Thrown by the tv-signal-off effect's internal compileShader helper when gl.createShader() returns null during effect setup. A null return from createShader means the WebGL2 context is lost, the GPU is out of memory, or the context was never validly initialized. The library fails fast rather than passing a null shader to subsequent GL calls, which would only produce a more confusing downstream error.
Source
Thrown at packages/effects/src/tv-signal-off.ts:134
void main() {
vec4 color = texture(uSource, vUv);
vec3 sourceColor = color.a == 0.0 ? vec3(0.0) : color.rgb / color.a;
vec3 bars = tvPattern(vUv);
vec3 mixed = mix(sourceColor, bars, uAmount);
fragColor = vec4(mixed * 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 shader');
}
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const info = gl.getShaderInfoLog(shader) ?? 'Unknown shader compile error';
gl.deleteShader(shader);
throw new Error(info);
}
return shader;
};
const createProgram = (
gl: WebGL2RenderingContext,
vertexSource: string,
fragmentSource: string,View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Reduce the number of concurrent render processes / parallelism so fewer simultaneous WebGL2 contexts are alive
- Ensure the headless browser has hardware GPU acceleration enabled (pass --use-gl=angle or the appropriate Chrome flags for your environment)
- Listen for the webglcontextlost event on the canvas and retry the render or effect setup after webglcontextrestored fires
- Update or replace GPU drivers; if using a VM, switch to one with GPU passthrough or a dedicated render GPU
Example fix
// before: many parallel renders exhaust GPU contexts
const {combineVideos} = await renderMedia({serveUrl, codec: 'h264', concurrency: 16});
// after: lower concurrency to reduce simultaneous GL contexts
await renderMedia({serveUrl, codec: 'h264', concurrency: 4}); Defensive patterns
Strategy: try-catch
Try / catch
try {
const state = setupTvSignalOffEffect(canvas);
} catch (err) {
if (err instanceof Error && err.message === 'Failed to create shader') {
// Context is lost or GPU resources exhausted — retry the whole render
// after a context restoration event or process restart.
throw new Error('WebGL2 context lost during tv-signal-off setup. Retry the render.');
}
throw err;
} Prevention
- Monitor the canvas webglcontextlost event and abort/retry the render proactively
- Keep concurrent render process count low enough that GPU context limits are not exceeded
- Ensure the headless browser has hardware GPU acceleration enabled via Chrome flags
When it happens
Trigger: The tvSignalOff effect's setup() calls createTvSignalOffState -> createProgram -> compileShader, and gl.createShader(gl.VERTEX_SHADER or gl.FRAGMENT_SHADER) returns null. This occurs when the WebGL2 context was acquired but is now in a WEBGL_lose_context lost state, or when the process has exhausted its GPU object allocation budget.
Common situations: Headless Chrome (Lambda, CI, Docker) with software rendering (SwiftShader) under memory pressure; too many concurrent Remotion render processes each holding their own GL context; a browser tab whose GL context was lost after a GPU driver crash or TDR; rendering on a machine where the GPU driver has crashed mid-render.
Related errors
- Failed to create program
- Failed to create WebGL resources
- Failed to create WebGL shader
- Failed to create WebGL program
- Failed to create WebGL vertex array
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/d7b2bef69524f97c.
Report an issue: GitHub.