{"record":{"id":"a6a37e834624d375","repo":"heygen-com/hyperframes","slug":"drawelement-canvas-not-initialized","errorCode":null,"errorMessage":"drawElement canvas not initialized","messagePattern":"drawElement canvas not initialized","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/engine/src/services/drawElementService.ts","lineNumber":334,"sourceCode":"  syncToPaintEvent = true,\n): Promise<Buffer> {\n  const dataUrl = await page.evaluate(\n    ({\n      w,\n      h,\n      fmt,\n      q,\n      sync,\n    }: {\n      w: number;\n      h: number;\n      fmt: \"jpeg\" | \"png\";\n      q: number;\n      sync: boolean;\n    }) => {\n      const canvas = document.getElementById(\"__hf_de_canvas\") as HTMLCanvasElement | null;\n      const root = document.querySelector(\"[data-composition-id]\") as HTMLElement | null;\n      if (!canvas || !root) throw new Error(\"drawElement canvas not initialized\");\n      const ctx = canvas.getContext(\"2d\");\n      if (!ctx) throw new Error(\"drawElement: 2d context unavailable\");\n      // Accelerated canvases (webgl/webgl2/webgpu) never repaint — their paint\n      // record stays frozen at the first frame (see instrumentAcceleratedCanvases).\n      // Hide them NOW, before this frame's paint, so the stale record stops\n      // painting; drawAndEncode composites their live content via drawImage\n      // underneath the drawElementImage output instead. Hiding must happen\n      // before the paint wait (sync mode) so the awaited paint reflects it.\n      type AccelWindow = Window & {\n        __hf_accel_canvases?: HTMLCanvasElement[];\n        __hf_canvas_2d?: HTMLCanvasElement[];\n        __hf3d?: { update: () => void };\n        __hfDeInvalidate?: () => boolean;\n        __HF_ROOT_PROPS__?: boolean;\n        __HF_ROOT_BASE_OPACITY__?: number;\n      };\n      const aw = window as AccelWindow;\n      // True when this frame's paint was requested via canvas.requestPaint()","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/engine/src/services/drawElementService.ts#L316-L352","documentation":"Thrown during the drawElement capture evaluate when document.getElementById('__hf_de_canvas') returns null or document.querySelector('[data-composition-id]') returns null. The canvas with id '__hf_de_canvas' is injected by injectDrawElementCanvas(); if that injection was never called, failed, or was reverted, the capture step cannot find its target.","triggerScenarios":"The capture function (drawAndEncode or its evaluate callback) runs page.evaluate to get the canvas element by id and the root by attribute. If injectDrawElementCanvas was skipped, threw before creating the canvas, or the page reloaded after injection, both lookups fail.","commonSituations":"injectDrawElementCanvas was not called before the first frame capture. The page navigated or reloaded between injection and capture. A composition script removed or replaced the canvas element. The canvas id was changed by a conflicting script.","solutions":["Ensure injectDrawElementCanvas(page, w, h) is called and awaited before any capture call.","If the page may navigate, re-inject after each navigation: call injectDrawElementCanvas again.","Check for composition scripts that manipulate document.body innerHTML and might destroy the canvas.","Add a guard: if document.getElementById('__hf_de_canvas') is null, re-run injection before capture."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const canvasReady = await page.evaluate(() =>\n  document.getElementById('__hf_de_canvas') !== null\n);\nif (!canvasReady) {\n  await injectDrawElementCanvas(page, w, h);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await captureDrawElement(page, captureOpts);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('canvas not initialized')) {\n    await injectDrawElementCanvas(page, w, h);\n    await captureDrawElement(page, captureOpts);\n  }\n  throw err;\n}","preventionTips":["Always call and await injectDrawElementCanvas before any capture call.","Re-inject after page navigations or reloads.","Guard the capture path with a canvas-existence check."],"tags":["drawelement","canvas","dom","lifecycle","browser"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}