remotion-dev/remotion · error · Error

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

Error message

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

What it means

Thrown by linkProgram() in fisheye-runtime.ts when gl.getProgramParameter(program, gl.LINK_STATUS) is false after gl.linkProgram() (fisheye-runtime.ts:57-61). Both fisheye shaders compiled, but the linker rejected the program — varying/uniform mismatch (uSource, uCenter, uFieldOfView, uRadius, uZoom, uAspect) or a driver linker bug. The InfoLog is included and the half-linked program is deleted.

Source

Thrown at packages/effects/src/fisheye/fisheye-runtime.ts:60

};

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

	return program;
};

const createProgram = (
	gl: WebGL2RenderingContext,
	vertexSource: string,
	fragmentSource: string,
): WebGLProgram => {
	const vs = compileShader(gl, gl.VERTEX_SHADER, vertexSource);
	const fs = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
	const program = linkProgram(gl, vs, fs);
	gl.deleteShader(vs);
	gl.deleteShader(fs);
	return program;
};

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Render with --gl=angle (CLI) / chromiumOptions.gl='angle' (SSR) / Angle (Studio) to use a stable linker.
  2. Read the InfoLog in the error; if it names a varying/uniform mismatch, verify fisheye-shaders.ts was not locally edited and that the vertex output (vUv) and fragment input match.
  3. Update GPU drivers or switch to a known-good software GL path.
  4. Confirm the context is healthy (gl.isContextLost()) and restore before retrying.
  5. Report the driver linker bug if the GLSL is valid and the InfoLog is nonsensical.

Example fix

// before
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
  // linker rejected fisheye program
}

// after (force a stable linker)
// CLI:  remotion render <comp> --gl=angle
// SSR:  renderMediaOnLambda({ chromiumOptions: { gl: 'angle' } })
Defensive patterns

Strategy: try-catch

Validate before calling

// No user input affects linking; FISHEYE_VS/FISHEYE_FS are fixed strings.
// Pre-check only context health before setup.
const isContextHealthy = (gl: WebGL2RenderingContext): boolean =>
  !gl.isContextLost();

Try / catch

try {
  // apply fisheye(); for a custom canvas: const state = setupFisheye(canvas);
} catch (err) {
  if (err instanceof Error && /Program link failed/.test(err.message)) {
    // err.message has the InfoLog; render on Angle and retry.
    console.error('fisheye link failure:', err.message);
    throw err;
  }
  throw err;
}

Prevention

When it happens

Trigger: setupFisheye() links FISHEYE_VS + FISHEYE_FS and LINK_STATUS comes back false. Because the shader contract (vUv + six uniforms) is fixed, a link failure points at a driver/translator linker bug, a degraded context, or a local edit that desynchronized the vertex/fragment varying declarations in fisheye-shaders.ts.

Common situations: Software GL / SwiftShader translators with buggy linkers in headless CI; outdated GPU drivers; a context partly broken after a GPU reset; local edits to fisheye-shaders.ts that broke the varying/uniform contract between stages.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/0452bd936331b0b7. Report an issue: GitHub.