{"record":{"id":"84518eeed6c8083b","repo":"Stirling-Tools/Stirling-PDF","slug":"failed-to-get-canvas-context-84518e","errorCode":null,"errorMessage":"Failed to get canvas context","messagePattern":"Failed to get canvas context","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/editor/src/core/utils/imageTransparency.ts","lineNumber":54,"sourceCode":"        img.src = e.target?.result as string;\n      };\n      reader.onerror = () => {\n        reject(new Error(\"Failed to read image file\"));\n      };\n      reader.readAsDataURL(imageFile);\n    }\n  });\n}\n\nfunction processImageTransparency(\n  img: HTMLImageElement,\n  options: TransparencyOptions,\n): string {\n  const canvas = document.createElement(\"canvas\");\n  const ctx = canvas.getContext(\"2d\");\n\n  if (!ctx) {\n    throw new Error(\"Failed to get canvas context\");\n  }\n\n  canvas.width = img.width;\n  canvas.height = img.height;\n\n  ctx.drawImage(img, 0, 0);\n\n  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n  const data = imageData.data;\n\n  let lowerBound = options.lowerBound || DEFAULT_LOWER_BOUND;\n  let upperBound = options.upperBound || DEFAULT_UPPER_BOUND;\n\n  if (options.autoDetectCorner) {\n    const cornerColor = detectCornerColor(imageData);\n    const tolerance = options.tolerance || 10;\n    lowerBound = {\n      r: Math.max(0, cornerColor.r - tolerance),","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/core/utils/imageTransparency.ts#L36-L72","documentation":"Thrown in processImageTransparency (removeWhiteBackground) after canvas.getContext(\"2d\") returned null. The function immediately calls ctx.drawImage and ctx.getImageData to read pixel data for white-background removal, so a null context is fatal. Same root class as the imageToPdfUtils case but on the transparency path where it must read pixel data.","triggerScenarios":"Invoking removeWhiteBackground on a system that cannot produce a 2D canvas context; privacy extensions blocking getImageData (some return a tainted/empty context instead of null); running the transparency feature in a non-browser test harness.","commonSituations":"Headless test runners without canvas polyfills; the same 100GB+ memory-pressure tab; canvas-read-blocking browser policies that cause getContext to return null.","solutions":["Guard the feature behind a capability check: attempt a tiny canvas getContext('2d') at module init and disable the transparency tool if unavailable.","Test in the target browser, not jsdom, since getImageData requires a real rendering backend.","Reduce concurrent image work to keep canvas backing-store allocation succeeding.","Catch the error at the UI layer and show a clear message rather than failing silently."],"exampleFix":"// before\nconst ctx = canvas.getContext(\"2d\");\nif (!ctx) throw new Error(\"Failed to get canvas context\");\n\n// after\nconst ctx = canvas.getContext(\"2d\", { willReadFrequently: true });\nif (!ctx) {\n  throw new Error(\n    \"Unable to start background removal: 2D canvas context unavailable in this browser/session.\",\n  );\n}","handlingStrategy":"type-guard","validationCode":"function supportsImageDataRead(): boolean {\n  try {\n    const c = document.createElement(\"canvas\");\n    c.width = 1; c.height = 1;\n    const ctx = c.getContext(\"2d\", { willReadFrequently: true });\n    return !!ctx && typeof ctx.getImageData === \"function\";\n  } catch {\n    return false;\n  }\n}","typeGuard":"const isCanvasContext = (ctx: CanvasRenderingContext2D | null): ctx is CanvasRenderingContext2D =>\n  ctx !== null;","tryCatchPattern":"try {\n  const result = await removeWhiteBackground(file, opts);\n} catch (error) {\n  if (error instanceof Error && error.message === \"Failed to get canvas context\") {\n    // show \"background removal unsupported in this browser\" UI\n  }\n  throw error;\n}","preventionTips":["Request willReadFrequently when reading pixels to avoid the software-canvas fallback cost.","Disable the transparency tool via capability check in test/headless contexts.","Limit concurrent transparency jobs to keep canvas memory available."],"tags":["canvas","browser-env","image-processing","getimagedata"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}