PaddlePaddle/PaddleOCR · error

worker mode requires Web Worker support in this environment.

Error message

worker mode requires Web Worker support in this environment.

What it means

In worker mode, if no custom createWorker is supplied, createDefaultWorker() constructs the bundled worker-entry module. It first checks that the global Worker constructor is a function; in environments without Web Workers (Node.js, some SSR/prerender contexts, restricted sandboxed iframes) it is undefined or not callable, so it throws instead of producing a confusing 'Worker is not defined' ReferenceError.

Source

Thrown at paddleocr-js/packages/core/src/pipelines/ocr/worker-backed.ts:17

/*
 * Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

import { sourceToWorkerPayload } from "../../platform/browser";
import { createWorkerTransportClient } from "../../worker/client";
import type { WorkerTransportClient, WorkerOptions } from "../../worker/client";
import type { OcrModelConfig, OcrRuntimeParamsInput } from "./runtime-params";
import type { InitializationSummary, OcrResult, OcrPipelineRunnerOptions } from "./core";
import { cloneDefaultOcrConfig } from "./shared";

declare const __ORT_WASM_CDN_PREFIX__: string | undefined;

function createDefaultWorker(): Worker {
  if (typeof Worker !== "function") {
    throw new Error("worker mode requires Web Worker support in this environment.");
  }
  return new Worker(new URL("./worker-entry.ts", import.meta.url), {
    type: "module"
  });
}

export class WorkerBackedPaddleOCR {
  private options: OcrPipelineRunnerOptions;
  private lastInitializationSummary: InitializationSummary | null;
  private modelConfig: OcrModelConfig;
  private transportClient: WorkerTransportClient;
  private initPromise: Promise<InitializationSummary> | null;
  private disposed: boolean;

  constructor(options: OcrPipelineRunnerOptions, transportClient: WorkerTransportClient) {
    this.options = options;
    this.lastInitializationSummary = null;
    this.modelConfig = cloneDefaultOcrConfig();

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Only enable worker mode in browser code paths (guard with typeof Worker !== 'undefined').
  2. In tests, use an environment with Worker support (real browser, Playwright/WebdriverIO) or polyfill Worker.
  3. For Node, run without worker mode (worker: false) if that path is supported for your use case.

Example fix

// before
const ocr = await PaddleOCR.create({ worker: true }); // called in Node/SSR

// after
const ocr = await PaddleOCR.create({
  worker: typeof Worker !== 'undefined'
});
Defensive patterns

Strategy: type-guard

Validate before calling

// Only request worker mode where Workers exist
if (typeof Worker !== 'function') {
  opts = { ...opts, worker: false };
}
const ocr = await PaddleOCR.create(opts);

Type guard

function supportsWebWorkers(): boolean {
  return typeof globalThis.Worker === 'function';
}

Try / catch

try {
  const ocr = await PaddleOCR.create({ worker: true });
} catch (e) {
  if (e instanceof Error && e.message.includes('requires Web Worker support')) {
    return PaddleOCR.create({ worker: false }); // run on the main thread instead
  }
  throw e;
}

Prevention

When it happens

Trigger: Running PaddleOCR.create({ worker: true }) in Node.js, Jest/vitest without jsdom+worker polyfills, or during SSR/prerendering; sandboxed iframes that block workers.

Common situations: Unit tests executing library imports against Node; Next.js/Nuxt server-side render paths accidentally invoking create(); assuming Node's worker_threads satisfies the browser Worker API.

Related errors


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