remotion-dev/remotion · error · Error

Could not create canvas context

Error message

Could not create canvas context

What it means

When copying a frame as an image from the sequence context menu, copyImageToClipboard creates an offscreen canvas and draws the source canvas into it. document.createElement('canvas')'s getContext('2d') returning null (rare, e.g. canvas blocked by browser policy or memory pressure) throws this error.

Solutions

  1. Retry the copy action — context allocation failures are often transient; closing unused tabs frees contexts.
  2. Reduce timeline zoom/thumbnail size or the composition resolution to lower canvas memory pressure.
  3. Check browser settings/enterprise policy that disables canvas (e.g. canvas readback blocking).
  4. Use an alternative export path (e.g. render a still via the CLI) if clipboard copy keeps failing.
Defensive patterns

Strategy: retry

Validate before calling

const probe = document.createElement('canvas').getContext('2d');
if (!probe) console.warn('2D canvas context unavailable in this environment');

Type guard

const has2d = (c: HTMLCanvasElement): c is HTMLCanvasElement & {getContext: (t: '2d') => CanvasRenderingContext2D} =>
  c.getContext('2d') !== null;

Try / catch

try {
  await copyImageToClipboard(el);
} catch (e) {
  if (e.message === 'Could not create canvas context') {
    // free contexts / retry once, else show a toast suggesting remotion still export
  } else throw e;
}

Prevention

When it happens

Trigger: Right-clicking a canvas-based frame in the Timeline and choosing the copy-image action while getContext('2d') returns null — typically when the browser cannot allocate a 2D context (out of memory, too many contexts, or canvas disabled by policy/privacy setting).

Common situations: Browsers at the ~16 active canvas-context limit in long Studio sessions; embedded browsers or kiosk modes with canvas disabled; very large canvases exhausting memory on low-RAM machines.

Related errors


AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18). Data as JSON: /api/errors/31e255ca85a8bca3. Report an issue: GitHub.

Appendix: source

Thrown at packages/studio/src/components/Timeline/get-sequence-context-menu-items.ts:67

): Element | null => {
	if (element?.tagName === 'CANVAS' || element?.tagName === 'VIDEO') {
		return element;
	}

	return element?.querySelector('canvas, video') ?? null;
};

const copyImageToClipboard = async (element: Element): Promise<void> => {
	let canvas: HTMLCanvasElement;

	if (element.tagName === 'CANVAS') {
		const sourceCanvas = element as HTMLCanvasElement;
		canvas = document.createElement('canvas');
		canvas.width = sourceCanvas.width;
		canvas.height = sourceCanvas.height;
		const context = canvas.getContext('2d');
		if (!context) {
			throw new Error('Could not create canvas context');
		}

		context.drawImage(sourceCanvas, 0, 0);
	} else if (element.tagName === 'IMG') {
		const image = element as HTMLImageElement;
		if (image.naturalWidth === 0 || image.naturalHeight === 0) {
			throw new Error('Image has not loaded');
		}

		canvas = document.createElement('canvas');
		canvas.width = image.naturalWidth;
		canvas.height = image.naturalHeight;
		const context = canvas.getContext('2d');
		if (!context) {
			throw new Error('Could not create canvas context');
		}

		context.drawImage(image, 0, 0);

View on GitHub (pinned to 46a3a6bf13)