remotion-dev/remotion · error · Error
Failed to create WebGL shader
Error message
Failed to create WebGL shader
What it means
Thrown inside compileShader() in fisheye-runtime.ts when gl.createShader(type) returns null (fisheye-runtime.ts:29-31). A null shader handle means the GL driver refused to allocate a shader object — context lost or shader-object pool exhausted. Without a handle, neither FISHEYE_VS nor FISHEYE_FS can be built, so fisheye setup aborts.
Source
Thrown at packages/effects/src/fisheye/fisheye-runtime.ts:30
textureSource: WebGLTexture;
uniforms: {
uSource: WebGLUniformLocation | null;
uCenter: WebGLUniformLocation | null;
uFieldOfView: WebGLUniformLocation | null;
uRadius: WebGLUniformLocation | null;
uZoom: WebGLUniformLocation | null;
uAspect: WebGLUniformLocation | null;
};
};
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(`Shader compile failed: ${log ?? '(no log)'}`);
}
return shader;
};
const linkProgram = (
gl: WebGL2RenderingContext,
vs: WebGLShader,
fs: WebGLShader,
): WebGLProgram => {View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Render with the Angle backend (--gl=angle CLI / chromiumOptions.gl='angle' SSR / Angle in Studio).
- If using fisheye-runtime directly, always pair setupFisheye() with cleanupFisheye() so shaders/programs are freed.
- Reduce simultaneous WebGL2 effects and reuse identical fisheye() params so calculateKey reuses one setup.
- Check gl.isContextLost() and restore the context before retrying.
- Update GPU drivers or use a host with adequate GL resources.
Example fix
// before
const shader = gl.createShader(type);
if (!shader) {
throw new Error('Failed to create WebGL shader');
}
// after (when using the runtime directly)
import {setupFisheye, cleanupFisheye} from '@remotion/effects/fisheye-runtime';
const state = setupFisheye(canvas);
try { /* applyFisheye(...) */ } finally { cleanupFisheye(state); } Defensive patterns
Strategy: try-catch
Validate before calling
const canAllocateShader = (gl: WebGL2RenderingContext): boolean => {
if (gl.isContextLost()) return false;
const probe = gl.createShader(gl.VERTEX_SHADER);
if (!probe) return false;
gl.deleteShader(probe);
return true;
}; Try / catch
import {setupFisheye, cleanupFisheye} from '@remotion/effects/fisheye-runtime';
let state;
try {
state = setupFisheye(canvas);
} catch (err) {
if (err instanceof Error && err.message === 'Failed to create WebGL shader') {
// context lost or shader pool exhausted; retry on Angle after cleanup
throw err;
}
throw err;
}
try { /* applyFisheye(state, ...) */ } finally { cleanupFisheye(state); } Prevention
- When using fisheye-runtime directly, always pair setupFisheye() with cleanupFisheye() so shaders/programs are freed.
- Render with Angle (--gl=angle / chromiumOptions.gl='angle').
- Limit simultaneous WebGL2 effects; reuse identical fisheye() params via calculateKey.
- Handle webglcontextlost and restore before retrying.
When it happens
Trigger: setupFisheye() -> createProgram() -> compileShader() runs while the WebGL2 context is lost (createShader must return null per spec) or after the driver's shader-object limit is reached from leaked/un-cleaned fisheye programs.
Common situations: Rendering on a host whose GPU process crashed leaving the context lost; long-running apps that call setupFisheye() directly without a matching cleanupFisheye(); CI with software GL and a low shader-object ceiling; many concurrent fisheye() instances.
Related errors
- Failed to create exposure shader
- Shader compile failed: ${log ?? '(no log)'}
- Failed to create WebGL program
- Program link failed: ${log ?? '(no log)'}
- Failed to create WebGL texture
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/8d79882f16c64b40.
Report an issue: GitHub.