{"record":{"id":"86c0594ffe77753f","repo":"remotion-dev/remotion","slug":"could-not-create-a-canvas-this-api-must-run-in-a","errorCode":null,"errorMessage":"Could not create a canvas. This API must run in a browser with OffscreenCanvas or the DOM available.","messagePattern":"Could not create a canvas\\. This API must run in a browser with OffscreenCanvas or the DOM available\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/video-matting/src/video-matting-canvas.ts","lineNumber":27,"sourceCode":"export const createVideoMattingCanvas = ({\n\twidth,\n\theight,\n}: {\n\twidth: number;\n\theight: number;\n}): VideoMattingCanvas => {\n\tif (typeof OffscreenCanvas !== 'undefined') {\n\t\treturn new OffscreenCanvas(width, height);\n\t}\n\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,","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/video-matting/src/video-matting-canvas.ts#L9-L45","documentation":"createVideoMattingCanvas needs a canvas to run the matting pipeline: it prefers OffscreenCanvas and falls back to document.createElement('canvas'). If neither OffscreenCanvas nor document exists (i.e. not running in a browser), it throws this Error. Video layer separation is a browser-only API requiring canvas support.","triggerScenarios":"Calling separateVideoLayers from Node.js, a Web Worker without OffscreenCanvas (old browsers), SSR code (server-side rendering of a component that eagerly invokes the API), or a jsdom-based test environment lacking OffscreenCanvas and real canvas creation.","commonSituations":"Next.js SSR importing the function into a server route; Jest/jsdom tests; Node scripts; extremely old browsers or web workers in Safari < 16.4 where OffscreenCanvas is missing in workers.","solutions":["Run the code only in a browser context — move the call into a client-side effect/handler, not module top-level or SSR.","Guard with typeof document !== 'undefined' || typeof OffscreenCanvas !== 'undefined' before calling.","In tests, either skip the test or use a browser-based test runner (Playwright) instead of jsdom.","In web workers, target browsers supporting OffscreenCanvas in workers (Chrome 69+, Safari 16.4+)."],"exampleFix":"// before\n// runs during SSR and crashes\nexport const loader = () => separateVideoLayers({src});\n// after\nexport const loader = () => {\n  if (typeof document === 'undefined') return null; // skip on server\n  return separateVideoLayers({src});\n};","handlingStrategy":"type-guard","validationCode":"if (typeof OffscreenCanvas === 'undefined' && typeof document === 'undefined') {\n  throw new Error('separateVideoLayers requires a browser environment');\n}","typeGuard":"const canRunVideoMatting = (): boolean =>\n  typeof OffscreenCanvas !== 'undefined' || typeof document !== 'undefined';","tryCatchPattern":"try {\n  await separateVideoLayers({src});\n} catch (e) {\n  if (e instanceof Error && e.message.includes('OffscreenCanvas or the DOM')) {\n    // not a browser: skip or reroute to server-side processing\n    return;\n  }\n  throw e;\n}","preventionTips":["Never call this API during SSR or in Node scripts; call it from client-side event handlers/effects.","In workers, target browsers with OffscreenCanvas support (Chrome 69+, Safari 16.4+).","Use browser-based test runners (Playwright) rather than jsdom for canvas code."],"tags":["browser-only","offscreenanvas","environment","ssr"],"backgroundTag":"unsupported-platform","analyzedSha":"b2f4e34732f3c6c222ea029413e22dc402218cd7","analyzedAt":"2026-09-09T13:27:51.281Z","contentChangedAt":"2026-09-09T13:27:51.281Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}