{"record":{"id":"8f3d36bd92c55b76","repo":"remotion-dev/remotion","slug":"could-not-create-a-2d-canvas-context","errorCode":null,"errorMessage":"Could not create a 2D canvas context.","messagePattern":"Could not create a 2D canvas context\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/video-matting/src/video-matting-canvas.ts","lineNumber":37,"sourceCode":"\n\tif (typeof document !== 'undefined') {\n\t\tconst canvas = document.createElement('canvas');\n\t\tcanvas.width = width;\n\t\tcanvas.height = height;\n\t\treturn canvas;\n\t}\n\n\tthrow new Error(\n\t\t'Could not create a canvas. This API must run in a browser with OffscreenCanvas or the DOM available.',\n\t);\n};\n\nexport const getVideoMattingCanvasContext = (\n\tcanvas: VideoMattingCanvas,\n): VideoMattingCanvasContext => {\n\tconst context = canvas.getContext('2d', {willReadFrequently: true});\n\tif (!context) {\n\t\tthrow new Error('Could not create a 2D canvas context.');\n\t}\n\n\treturn context as VideoMattingCanvasContext;\n};\n\nexport const drawOpaqueBaseFrame = ({\n\tcontext,\n\tsource,\n\twidth,\n\theight,\n}: {\n\tcontext: VideoMattingCanvasContext;\n\tsource: VideoMattingCanvas;\n\twidth: number;\n\theight: number;\n}) => {\n\tcontext.save();\n\tcontext.globalCompositeOperation = 'copy';","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/video-matting/src/video-matting-canvas.ts#L19-L55","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst ctx = sharedCanvas.getContext('webgl'); // poisons future 2d requests downstream\nawait separateVideoLayers({src});\n// after\nconst ctx = sharedCanvas.getContext('2d');\nawait separateVideoLayers({src});","handlingStrategy":"try-catch","validationCode":"const test = document.createElement('canvas');\nif (!test.getContext('2d')) {\n  throw new Error('This environment cannot create a 2D canvas context');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await separateVideoLayers({src});\n} catch (e) {\n  if (e instanceof Error && e.message.includes('2D canvas context')) {\n    // likely too many live canvases or a poisoned canvas — retry after cleanup\n    releaseCanvases();\n    return separateVideoLayers({src});\n  }\n  throw e;\n}","preventionTips":["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)."],"tags":["canvas","webcodecs","context","browser-support"],"backgroundTag":"unsupported-operation","analyzedSha":"b2f4e34732f3c6c222ea029413e22dc402218cd7","analyzedAt":"2026-09-09T13:27:51.281Z","contentChangedAt":"2026-09-09T13:27:51.281Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}