PaddlePaddle/PaddleOCR · error
PaddleOCR worker instance has been disposed.
Error message
PaddleOCR worker instance has been disposed.
What it means
WorkerBackedPaddleOCR tracks a disposed flag set by dispose(). Every public method calls ensureActive() first and throws this error after disposal, preventing use of a terminated worker whose transport client no longer has a live counterpart.
Source
Thrown at paddleocr-js/packages/core/src/pipelines/ocr/worker-backed.ts:43
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();
this.transportClient = transportClient;
this.initPromise = null;
this.disposed = false;
}
ensureActive(): void {
if (this.disposed) {
throw new Error("PaddleOCR worker instance has been disposed.");
}
}
async initialize(): Promise<InitializationSummary> {
this.ensureActive();
if (this.lastInitializationSummary) {
return this.lastInitializationSummary;
}
if (!this.initPromise) {
const ortOpts = (this.options.ortOptions || {}) as Record<string, unknown>;
if (ortOpts["wasmPaths"] === undefined && typeof __ORT_WASM_CDN_PREFIX__ === "string") {
console.warn(
"[PaddleOCR.js] Worker mode: ortOptions.wasmPaths is not set — falling back to CDN (%s). " +
"For version consistency between main thread and worker, set ortOptions.wasmPaths " +
"to the path where your bundler outputs the onnxruntime-web WASM files " +
'(e.g. ortOptions: { wasmPaths: "/assets/" }).',
__ORT_WASM_CDN_PREFIX__
);View on GitHub (pinned to 2661c7c0ef)
Solutions
- Create a fresh instance via PaddleOCR.create() after disposing instead of reusing the old one.
- Serialize teardown: await outstanding predict() promises before calling dispose().
- For shared instances, reference-count users and dispose only when the count reaches zero.
Example fix
// before await ocr.dispose(); const result = await ocr.predict(image); // throws // after await ocr.dispose(); const ocr2 = await PaddleOCR.create(); const result = await ocr2.predict(image);
Defensive patterns
Strategy: validation
Validate before calling
// Track your own lifecycle: never call predict() after dispose()
let disposed = false;
async function teardown() {
disposed = true;
await inFlight; // settle outstanding predictions
await ocr.dispose();
}
if (!disposed) await ocr.predict(img); Try / catch
try {
await ocr.predict(image);
} catch (e) {
if (e instanceof Error && e.message === 'PaddleOCR worker instance has been disposed.') {
ocr = await PaddleOCR.create(opts); // recreate and optionally retry once
return ocr.predict(image);
}
throw e;
} Prevention
- Await all in-flight predictions before dispose(); keep a promise counter if calls are frequent.
- Reference-count shared instances across components before tearing down.
- Do not reuse an instance after dispose() — always create a new one.
When it happens
Trigger: Calling predict(), initialize(), setRuntimeParams(), etc. on a WorkerBackedPaddleOCR instance after await instance.dispose(); also double-dispose followed by reuse, or a race where a queued call resolves after dispose().
Common situations: Cleaning up on component unmount / route change while an in-flight prediction continues; shared singleton disposed by one consumer while another still uses it; React StrictMode double effects disposing then reusing.
Related errors
- OCR worker is not initialized.
- Worker transport client has been disposed.
- 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/4372db251887a5e6.
Report an issue: GitHub.