remotion-dev/remotion · error · Error
Could not create a 2D canvas context.
Error message
Could not create a 2D canvas context.
What it means
canvas.getContext('2d', {willReadFrequently: true}) returned null, so no 2D rendering context could be created for the matting canvas. The library needs pixel readback (willReadFrequently) to run the matting model and draw output frames; without a 2D context it cannot proceed and throws.
Source
Thrown at packages/video-matting/src/video-matting-canvas.ts:37
if (typeof document !== 'undefined') {
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
return canvas;
}
throw new Error(
'Could not create a canvas. This API must run in a browser with OffscreenCanvas or the DOM available.',
);
};
export const getVideoMattingCanvasContext = (
canvas: VideoMattingCanvas,
): VideoMattingCanvasContext => {
const context = canvas.getContext('2d', {willReadFrequently: true});
if (!context) {
throw new Error('Could not create a 2D canvas context.');
}
return context as VideoMattingCanvasContext;
};
export const drawOpaqueBaseFrame = ({
context,
source,
width,
height,
}: {
context: VideoMattingCanvasContext;
source: VideoMattingCanvas;
width: number;
height: number;
}) => {
context.save();
context.globalCompositeOperation = 'copy';View on GitHub (pinned to b2f4e34732)
Solutions
- Free finished work: null out references to prior canvases/contexts so the browser can reclaim contexts.
- Don't call getContext('webgl'/'webgpu') on canvases managed by this library.
- Catch the error and retry once with a fresh OffscreenCanvas if the context limit was transient.
- Reduce concurrent separateVideoLayers calls so fewer canvases exist at once.
Example fix
// before
const ctx = sharedCanvas.getContext('webgl'); // poisons future 2d requests downstream
await separateVideoLayers({src});
// after
const ctx = sharedCanvas.getContext('2d');
await separateVideoLayers({src}); Defensive patterns
Strategy: try-catch
Validate before calling
const test = document.createElement('canvas');
if (!test.getContext('2d')) {
throw new Error('This environment cannot create a 2D canvas context');
} Try / catch
try {
await separateVideoLayers({src});
} catch (e) {
if (e instanceof Error && e.message.includes('2D canvas context')) {
// likely too many live canvases or a poisoned canvas — retry after cleanup
releaseCanvases();
return separateVideoLayers({src});
}
throw e;
} Prevention
- Don't request webgl/webgpu contexts on canvases used by this library.
- Release canvas references after each separation run to avoid browser context limits.
- Limit concurrent separation jobs (e.g. one at a time).
When it happens
Trigger: Requesting a '2d' context from a canvas that already yielded a different context type ('webgl'/'webgpu'); browser limits on total number of canvas contexts being exhausted (too many canvases alive); a context lost due to GPU constraints; canvas of zero size in some engines.
Common situations: Mixing the library with code that previously grabbed a WebGL context on the same canvas (rare, since the library creates its own); pages creating hundreds of canvases until the browser's context limit is hit; GPU-driver crashes marking contexts lost in long-running sessions.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- No supported configs
- Your browser does not support the WebCodecs ImageDecoder API
- Failed to acquire 2D context for output canvas
- The primary video track cannot be decoded.
- This browser cannot encode the VP9 video streams required fo
AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09).
Data as JSON: /api/errors/8f3d36bd92c55b76.
Report an issue: GitHub.