PaddlePaddle/PaddleOCR · error · Error

Failed to create 2D rendering context.

Error message

Failed to create 2D rendering context.

What it means

Thrown by getContext2D() in viz/canvas-factory when canvas.getContext("2d") returns null for either an HTMLCanvasElement or OffscreenCanvas. Visualization APIs (drawing detection boxes, rendering results to canvas/blob) need this context. Null typically means too many live contexts, a conflicting context type already bound to the canvas, or a DOM-less environment.

Source

Thrown at paddleocr-js/packages/core/src/viz/canvas-factory.ts:23

type AnyCanvas = OffscreenCanvas | HTMLCanvasElement;

export function createCanvas(width: number, height: number): AnyCanvas {
  if (typeof OffscreenCanvas !== "undefined") {
    return new OffscreenCanvas(width, height);
  }
  const canvas = document.createElement("canvas");
  canvas.width = width;
  canvas.height = height;
  return canvas;
}

export function getContext2D(
  canvas: AnyCanvas
): CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D {
  const ctx = canvas.getContext("2d");
  if (!ctx) {
    throw new Error("Failed to create 2D rendering context.");
  }
  return ctx;
}

export function canvasToBlob(canvas: AnyCanvas, type: string, quality: number): Promise<Blob> {
  if (canvas instanceof OffscreenCanvas) {
    return canvas.convertToBlob({ type, quality });
  }
  return new Promise<Blob>((resolve, reject) => {
    canvas.toBlob(
      (blob) => {
        if (blob) {
          resolve(blob);
        } else {
          reject(new Error("canvas.toBlob() returned null."));
        }
      },
      type,

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Use a fresh canvas (or one previously used with "2d") for visualization output instead of one holding a WebGL context
  2. Free old canvases (zero out width/height, drop references) before creating new ones
  3. Install the 'canvas' npm package for jsdom-based tests
  4. Render fewer, larger canvases or reuse one overlay canvas across frames

Example fix

// before
const ctx = glCanvas.getContext("2d"); // null: webgl already bound -> library throws

// after
const overlay = document.createElement("canvas"); // dedicated 2D canvas
overlay.width = img.width; overlay.height = img.height;
const ctx = overlay.getContext("2d");
Defensive patterns

Strategy: validation

Validate before calling

function canvasAccepts2d(canvas: HTMLCanvasElement | OffscreenCanvas): boolean {
  return canvas.getContext("2d") !== null;
}

Try / catch

try {
  const ctx = getContext2D(overlayCanvas);
  drawResults(ctx, result);
} catch (e) {
  if (e instanceof Error && e.message.includes("2D rendering context")) {
    const fresh = document.createElement("canvas"); // retry with a clean canvas
    drawResults(getContext2D(fresh), result);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling a viz/render API on a canvas that already has a "webgl"/"webgpu" context bound; after the page exhausted its canvas context budget; in jsdom or SSR where 2D contexts are not implemented.

Common situations: Reusing a WebGL canvas for OCR overlay drawing; long sessions rendering many result canvases; unit tests of visualization code under jsdom without the 'canvas' polyfill.

Related errors


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/b6fdff1947a15907. Report an issue: GitHub.