remotion-dev/remotion · error

Tear program link failed: ${log ?? '(no log)'}

Error message

Tear program link failed: ${log ?? '(no log)'}

What it means

The Tear effect's vertex and fragment shaders compiled individually but failed to link into a program (gl.LINK_STATUS false). The library reads gl.getProgramInfoLog(), deletes the program, and throws with the driver's log. Common causes are the driver refusing to link (resource limits, driver bugs) rather than authoring errors, since the effect's shaders are prebuilt.

Source

Thrown at packages/effects/src/tear.ts:215

};

const linkProgram = (
	gl: WebGL2RenderingContext,
	vs: WebGLShader,
	fs: WebGLShader,
): WebGLProgram => {
	const program = gl.createProgram();
	if (!program) {
		throw new Error('Failed to create WebGL program');
	}

	gl.attachShader(program, vs);
	gl.attachShader(program, fs);
	gl.linkProgram(program);
	if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
		const log = gl.getProgramInfoLog(program);
		gl.deleteProgram(program);
		throw new Error(`Tear program link failed: ${log ?? '(no log)'}`);
	}

	return program;
};

const createTearState = (gl: WebGL2RenderingContext): TearState => {
	const vs = compileShader(gl, gl.VERTEX_SHADER, VERTEX_SHADER);
	const fs = compileShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER);
	const program = linkProgram(gl, vs, fs);
	gl.deleteShader(vs);
	gl.deleteShader(fs);

	const vao = gl.createVertexArray();
	if (!vao) {
		throw new Error('Failed to create WebGL vertex array');
	}

	gl.bindVertexArray(vao);

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Read the appended link log for the driver's specific reason
  2. Update GPU drivers and the browser
  3. Free GPU resources (other effects, tabs, contexts) and retry
  4. If headless, switch to a GPU-backed environment or newer SwiftShader
  5. Report to Remotion with the log if it reproduces on current drivers

Example fix

// before (rendering with outdated llvmpipe in CI)
// container uses old mesa
// after
// pin a newer Chrome/Mesa image, e.g. playwright image with current deps
// docker run mcr.microsoft.com/playwright:vlatest
Defensive patterns

Strategy: try-catch

Validate before calling

const gl = canvas.getContext('webgl2');
if (!gl) throw new Error('WebGL2 unavailable');
const vs = gl.createShader(gl.VERTEX_SHADER)!;
gl.shaderSource(vs, '#version 300 es\nin vec2 aPos; void main(){ gl_Position = vec4(aPos,0.0,1.0); }');
gl.compileShader(vs);
const p = gl.createProgram();
gl.attachShader(p, vs);
gl.linkProgram(p);
const linkOk = gl.getProgramParameter(p, gl.LINK_STATUS);
gl.deleteProgram(p); gl.deleteShader(vs);
if (!linkOk) throw new Error('Program linking unsupported on this driver: ' + gl.getProgramInfoLog(p));

Type guard

function canLinkPrograms(gl: WebGL2RenderingContext): boolean {
  return !gl.isContextLost() && gl.getProgramParameter !== undefined;
}

Try / catch

try {
  renderWithTear(...);
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Tear program link failed')) {
    console.error('GL link log:', err.message);
    // switch to a non-WebGL fallback effect or a different machine/driver
  } else throw err;
}

Prevention

When it happens

Trigger: gl.linkProgram() failing during Tear state creation, typically after a driver/GPU resource problem, or on drivers with buggy GLSL ES 3.00 linkers; also possible if the context became lost between compile and link steps.

Common situations: Headless/CI software rasterizers with incomplete program linking; GPU memory exhaustion (too many compiled programs/textures); known driver bugs on older Intel/ANGLE versions; browser regressions.

Related errors


AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09). Data as JSON: /api/errors/62b1f86de9a259d4. Report an issue: GitHub.