PaddlePaddle/PaddleOCR · error · Error

Worker transport client requires a createWorker() factory.

Error message

Worker transport client requires a createWorker() factory.

What it means

Thrown by WorkerTransportClient.ensureWorker() when lazily spinning up the worker and finding that workerOptions.createWorker is not a function. The transport deliberately does not hardcode a Worker constructor (bundle paths differ per app), so the caller must inject a factory. Omitting it means the client was constructed with no or malformed options.

Source

Thrown at paddleocr-js/packages/core/src/worker/client.ts:46

    this.nextRequestId = 1;
    this.disposed = false;
  }

  ensureActive(): void {
    if (this.disposed) {
      throw new Error("Worker transport client has been disposed.");
    }
  }

  ensureWorker(): Worker {
    this.ensureActive();
    if (this.worker) {
      return this.worker;
    }

    const workerFactory = this.workerOptions.createWorker;
    if (typeof workerFactory !== "function") {
      throw new Error("Worker transport client requires a createWorker() factory.");
    }
    const worker = workerFactory();
    worker.onmessage = (event: MessageEvent) => {
      const message = event.data as unknown;
      if (!isTransportResponse(message)) return;
      const pending = this.pending.get(message.requestId);
      if (!pending) return;
      this.pending.delete(message.requestId);
      if (message.status === "success") {
        pending.resolve(message.payload);
      } else {
        pending.reject(deserializeError(message.error));
      }
    };
    worker.onerror = (event: ErrorEvent) => {
      const error = new Error(event.message || "OCR worker failed.");
      for (const pending of this.pending.values()) {
        pending.reject(error);

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Pass a factory returning the bundled worker: { createWorker: () => new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }) }
  2. If you only need OCR, use the high-level API which provides the factory automatically
  3. Type the options object against the exported WorkerOptions interface so the missing field is a compile error

Example fix

// before
const client = new WorkerTransportClient(); // no options -> throws on first use

// after
const client = new WorkerTransportClient({
  createWorker: () => new Worker(new URL("./ocr-worker.js", import.meta.url), { type: "module" })
});
Defensive patterns

Strategy: type-guard

Validate before calling

const opts: WorkerOptions = {
  createWorker: () => new Worker(new URL("./ocr.worker.js", import.meta.url), { type: "module" })
};
assert(typeof opts.createWorker === "function");

Type guard

function hasWorkerFactory(o: unknown): o is { createWorker: () => Worker } {
  return typeof (o as { createWorker?: unknown })?.createWorker === "function";
}

Prevention

When it happens

Trigger: new WorkerTransportClient() with no options in a custom integration; passing { createWorker: undefined } after a refactor; options object built by a function that forgot the field in one branch; bundler tree-shaking or mock setup dropping the factory.

Common situations: Advanced users wiring the low-level worker transport manually instead of the high-level API; test doubles not implementing createWorker; copying example code that assumed defaults.

Related errors


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