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
- Ensure tint (a `backend: '2d'` effect) is not combined on the same canvas pass as a webgl2 effect that already acquired a GL context.
- Run in an environment with full Canvas 2D support (standard browser or headless Chrome).
- If building a custom pipeline, give each effect backend a fresh canvas rather than reusing one across context types.
- 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
- Do not mix `backend: '2d'` effects with webgl2 effects on the same canvas pass — ensure pipeline isolation.
- Run in an environment with Canvas 2D support (standard browser / headless Chrome).
- In custom pipelines, allocate a fresh canvas per backend rather than reusing one across context types.
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
- Failed to acquire 2D context for translate effect. The canva
- Failed to acquire 2D context for color parsing
- Failed to acquire 2D context for output canvas
- useLogLevel must be used within a LogLevelProvider
- useMountTime must be used within a LogLevelProvider
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/9d9dd762f9cca33b.
Report an issue: GitHub.