remotion-dev/remotion · critical · Error

Failed to acquire 2D context for tint effect. The canvas may

Error message

Failed to acquire 2D context for tint effect. The canvas may have been assigned a different context type.

What it means

The tint effect (2D backend) calls `target.getContext('2d')` on the effect's target canvas at the start of `apply`. If this returns `null`, the effect cannot draw. Because the target canvas is provided by the rendering pipeline and the effect declares `backend: '2d'`, a null 2D context normally means the canvas was already assigned a different (e.g. webgl) context, or the 2D backend is unavailable in the environment.

Source

Thrown at packages/effects/src/tint.ts:74

};

// Tints the source with a flat color. `amount` controls the blend strength
// (0 = no tint, 1 = full color over opaque pixels). Operates on the 2D
// backend; tinting respects the source's alpha mask.
export const tint = createEffect<TintParams, null>({
	type: 'dev.remotion.effects.tint',
	label: 'tint()',
	documentationLink: 'https://www.remotion.dev/docs/effects/tint',
	backend: '2d',
	calculateKey: (params) => {
		const r = resolve(params);
		return `tint-${r.color}-${r.amount}`;
	},
	setup: () => null,
	apply: ({source, target, width, height, params}) => {
		const ctx = target.getContext('2d');
		if (!ctx) {
			throw new Error(
				'Failed to acquire 2D context for tint effect. The canvas may have been assigned a different context type.',
			);
		}

		const r = resolve(params);
		const amount = Math.max(0, Math.min(1, r.amount));

		ctx.clearRect(0, 0, width, height);
		ctx.globalAlpha = 1;
		ctx.globalCompositeOperation = 'source-over';
		ctx.drawImage(source, 0, 0, width, height);

		// `source-atop` only paints inside non-transparent regions of the source,
		// so the tint respects the source's alpha mask.
		ctx.globalAlpha = amount;
		ctx.globalCompositeOperation = 'source-atop';
		ctx.fillStyle = r.color;
		ctx.fillRect(0, 0, width, height);

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Ensure tint (a `backend: '2d'` effect) is not combined on the same canvas pass as a webgl2 effect that already acquired a GL context.
  2. Run in an environment with full Canvas 2D support (standard browser or headless Chrome).
  3. If building a custom pipeline, give each effect backend a fresh canvas rather than reusing one across context types.
  4. Report to maintainers if this occurs in stock Remotion Studio/render without custom canvas sharing.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  tint({...params});
} catch (e) {
  if (/Failed to acquire 2D context for tint/.test((e as Error).message)) {
    // target canvas has a foreign context or 2D is unavailable; skip effect
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: The target canvas already requested a `'webgl'` or `'webgl2'` context (a canvas can only have one context type); the 2D canvas backend is unavailable in the runtime; a pipeline bug passed a canvas already bound to a different context.

Common situations: Mixing 2D and webgl2 effects on the same underlying canvas where the pipeline does not isolate them; a custom render host reusing canvas elements across context types; an environment with Canvas 2D disabled.

Related errors


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