PaddlePaddle/PaddleOCR · error
worker mode does not support a custom fetch implementation.
Error message
worker mode does not support a custom fetch implementation.
What it means
PaddleOCR.create() throws this when you enable worker mode (options.worker is true or an options object) and also pass a custom fetch implementation (options.fetch). In worker mode the pipeline runs inside a Web Worker and fetch cannot be serialized or transferred across the worker boundary, so the combination is rejected up front rather than silently ignored.
Source
Thrown at paddleocr-js/packages/core/src/pipelines/ocr/index.ts:80
[key: string]: unknown;
}
export class PaddleOCR extends OcrPipelineRunner {
constructor(options: OcrPipelineRunnerOptions) {
super({
...options,
ensureServedFromHttp,
sourceToMat
});
}
static async create(
options: PaddleOCRCreateOptions = {}
): Promise<PaddleOCR | WorkerBackedPaddleOCR> {
const workerOptions = resolveWorkerOptions(options.worker);
if (workerOptions.enabled && options.fetch) {
throw new Error("worker mode does not support a custom fetch implementation.");
}
const resolvedOptions = resolvePaddleOCROptions(options);
const instance = workerOptions.enabled
? createWorkerBackedPaddleOCR(resolvedOptions, {
createWorker: workerOptions.createWorker ?? undefined
})
: new PaddleOCR({
...resolvedOptions,
fetch: options.fetch
});
if (options.initialize !== false) {
await instance.initialize();
}
return instance;
}
}View on GitHub (pinned to 2661c7c0ef)
Solutions
- Remove the fetch option when worker mode is enabled; the worker performs its own fetches.
- If you need custom networking, keep worker disabled (worker: false or unset) so fetch is honored on the main thread.
- If the custom fetch exists for asset URL rewriting, instead override the model/asset URLs via model selection options (e.g. *_model_dir / ModelAsset) which are plain data and worker-safe.
Example fix
// before
const ocr = await PaddleOCR.create({ worker: true, fetch: authedFetch });
// after
const ocr = await PaddleOCR.create({ worker: true });
// or keep custom fetch on the main thread:
const ocr = await PaddleOCR.create({ fetch: authedFetch }); Defensive patterns
Strategy: validation
Validate before calling
// Before create(): worker + fetch are mutually exclusive
const wantsWorker = options.worker === true || (typeof options.worker === 'object' && options.worker !== null);
if (wantsWorker && options.fetch) {
throw new TypeError('Custom fetch is not supported with worker: true. Remove fetch or disable worker mode.');
} Type guard
function isSafeCreateOptions(o: { worker?: unknown; fetch?: unknown }): boolean {
const workerEnabled = o.worker === true || (typeof o.worker === 'object' && o.worker !== null);
return !(workerEnabled && o.fetch != null);
} Try / catch
try {
const ocr = await PaddleOCR.create(opts);
} catch (e) {
if (e instanceof Error && e.message.includes('does not support a custom fetch')) {
// retry without fetch (worker performs its own fetching)
const { fetch: _f, ...rest } = opts;
return PaddleOCR.create(rest);
}
throw e;
} Prevention
- Centralize PaddleOCR.create() in one factory function that asserts worker and fetch are never both set.
- Document in your config schema that customFetch and workerMode are mutually exclusive.
When it happens
Trigger: Calling PaddleOCR.create({ worker: true, fetch: myFetch }) or PaddleOCR.create({ worker: { createWorker: () => new Worker(...) }, fetch: customFetch }). resolveWorkerOptions() returns enabled=true and options.fetch is truthy.
Common situations: Adding a fetch wrapper (auth headers, proxying, offline caching) to an existing integration and then turning on worker mode for performance; copying a main-thread configuration object into a worker-mode create() call.
Related errors
- worker must be a boolean or an options object.
- Conflicting values provided for ${label}: ${aliases.join(",
- ${modelRole} model selection must define model_name.
- OCR model selection must define both detection and recogniti
- Worker transport client requires a createWorker() factory.
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/9cb2ac63884bfa32.
Report an issue: GitHub.