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
- Pass a factory returning the bundled worker: { createWorker: () => new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }) }
- If you only need OCR, use the high-level API which provides the factory automatically
- 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
- Type constructor calls against the exported WorkerOptions interface
- Prefer the high-level API which injects the factory for you
- Assert the factory exists in test doubles/mocks
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
- OCR pipeline config must be an object or YAML text.
- File not found: ${path}
- Bad request: ${text}
- OCR pipeline config text must decode to an object.
- ${modulePath}.model_dir must be null or an asset descriptor
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/3cbf728a9e086563.
Report an issue: GitHub.