PaddlePaddle/PaddleOCR · critical

PaddleOCR source adapter is not configured.

Error message

PaddleOCR source adapter is not configured.

What it means

Thrown by OcrPipelineRunner.predict() when no sourceToMat adapter is configured. The core is source-agnostic: it never decodes images itself, and relies on an injected sourceToMat function to turn whatever input type you pass (URL, Blob, HTMLImageElement) into an OpenCV Mat. If the layer that installs the adapter was skipped, predict refuses to run.

Source

Thrown at paddleocr-js/packages/core/src/pipelines/ocr/core.ts:199

      recProvider: this.recModel.provider,
      assets: loadedAssets.map((asset) => asset.download),
      elapsedMs: elapsed,
      pipelineConfigWarnings: this.pipelineConfig.warnings
    };
    return this.lastInitializationSummary;
  }

  getInitializationSummary(): InitializationSummary | null {
    return this.lastInitializationSummary;
  }

  getModelConfig(): OcrModelConfig {
    return this.modelConfig;
  }

  async predict(input: unknown, params: OcrRuntimeParamsInput = {}): Promise<OcrResult[]> {
    if (!this.sourceToMat) {
      throw new Error("PaddleOCR source adapter is not configured.");
    }
    if (!this.detModel || !this.recModel || !this.cv || !this.ort) {
      await this.initialize();
    }

    const cv = this.cv;
    const detModel = this.detModel;
    const recModel = this.recModel;
    if (!cv || !detModel || !recModel) {
      throw new Error("Initialization did not complete. Call initialize() first.");
    }

    const sources = Array.isArray(input) ? input : [input];
    const sourceToMat = this.sourceToMat;
    const pipelineBatchSize = Math.max(1, Math.floor(this.pipelineConfig.pipelineBatchSize) || 1);
    const sourceBatches = chunkArray(sources, pipelineBatchSize);

    const totalStart = nowMs();

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Prefer the high-level browser entry point (e.g. the paddleocr-js browser/web package) which configures sourceToMat automatically
  2. Or pass a sourceToMat option implementing your input type → cv.Mat conversion when constructing the runner
  3. Check the runner was created through the intended factory rather than new OcrPipelineRunner(...)

Example fix

// before
const runner = new OcrPipelineRunner(coreOpts); // no sourceToMat
await runner.predict(imageUrl); // throws

// after
const runner = new OcrPipelineRunner({ ...coreOpts, sourceToMat: browserSourceToMat });
await runner.predict(imageUrl);
Defensive patterns

Strategy: validation

Validate before calling

// Coarse check: the runner exposes no public sourceToMat, so validate construction instead
if (!("sourceToMat" in runnerOptions) && !usedHighLevelFactory) {
  throw new Error("No source adapter configured — pass sourceToMat or use the browser entry point");
}

Type guard

function hasSourceAdapter(runner: { sourceToMat?: unknown }): boolean {
  return typeof runner.sourceToMat === "function";
}

Try / catch

try { await runner.predict(input); } catch (e) {
  if (e instanceof Error && /source adapter is not configured/.test(e.message)) {
    // construct via the browser wrapper or supply sourceToMat, then retry
  } else throw e;
}

Prevention

When it happens

Trigger: Instantiating the core-level runner directly (which does not set sourceToMat) and calling predict("https://...") or predict(blob); using a custom build/entry point that forgot to pass the sourceToMat option; calling predict after a reset that cleared the adapter.

Common situations: Using the core package instead of the browser/react wrapper that bundles the image-decoding adapter; Node usage where no default adapter exists; partial initialization path that skips adapter setup on an error branch.

Related errors


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