PaddlePaddle/PaddleOCR · error · Error
Worker transport client has been disposed.
Error message
Worker transport client has been disposed.
What it means
Thrown by WorkerTransportClient.ensureActive() when any operation is attempted after dispose() was called. The client sets disposed = true on teardown (worker terminated, pending rejected); every subsequent recognize/rpc call re-checks the flag and fails fast rather than silently operating on a dead transport. This is a lifecycle-contract error: the instance is single-use after disposal.
Source
Thrown at paddleocr-js/packages/core/src/worker/client.ts:34
export class WorkerTransportClient {
private workerOptions: WorkerOptions;
private worker: Worker | null;
private pending: Map<number, PendingRequest>;
private nextRequestId: number;
private disposed: boolean;
constructor(workerOptions: WorkerOptions = {}) {
this.workerOptions = workerOptions;
this.worker = null;
this.pending = new Map();
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);View on GitHub (pinned to 2661c7c0ef)
Solutions
- Create a fresh WorkerTransportClient (or re-create the OCR instance) after disposing
- Null the reference on dispose and guard call sites with the disposed check
- Cancel/await pending work before calling dispose in teardown logic
Example fix
// before client.dispose(); await client.recognize(img); // throws: disposed // after client.dispose(); client = createWorkerTransport(options); // new client for further work await client.recognize(img);
Defensive patterns
Strategy: type-guard
Validate before calling
// call before every use client.ensureActive(); // throws early with a clear message
Type guard
function isActiveClient(c: { ensureActive(): void }): boolean {
try { c.ensureActive(); return true; } catch { return false; }
} Try / catch
try {
return await client.recognize(img);
} catch (e) {
if (e instanceof Error && e.message.includes("disposed")) {
client = createClient(); // rebuild transport and retry once
return await client.recognize(img);
}
throw e;
} Prevention
- Null out references in dispose() teardown paths
- Await or cancel in-flight work before disposing
- Re-create the client after dispose instead of reusing it
When it happens
Trigger: Awaiting client.dispose() (or an error path that disposes) and then issuing another request; shared client held in app state that gets disposed on unmount but referenced later by a lingering promise/timer; React StrictMode double-mount disposing a client another effect still uses.
Common situations: Component unmount racing an in-flight recognition that retries; hot module replacement disposing the old client while callbacks still hold it; caching the client in a module-level variable without resetting it after dispose.
Related errors
- PaddleOCR worker instance has been disposed.
- OCR worker is not initialized.
- Detection model session is not initialized.
- Recognition model session is not initialized.
- PaddleOCRCore requires pre-resolved detection and recognitio
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/28c25edf8f4a7f11.
Report an issue: GitHub.