{"record":{"id":"c6f2aad174daf54c","repo":"PaddlePaddle/PaddleOCR","slug":"paddleocr-source-adapter-is-not-configured","errorCode":null,"errorMessage":"PaddleOCR source adapter is not configured.","messagePattern":"PaddleOCR source adapter is not configured\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"paddleocr-js/packages/core/src/pipelines/ocr/core.ts","lineNumber":199,"sourceCode":"      recProvider: this.recModel.provider,\n      assets: loadedAssets.map((asset) => asset.download),\n      elapsedMs: elapsed,\n      pipelineConfigWarnings: this.pipelineConfig.warnings\n    };\n    return this.lastInitializationSummary;\n  }\n\n  getInitializationSummary(): InitializationSummary | null {\n    return this.lastInitializationSummary;\n  }\n\n  getModelConfig(): OcrModelConfig {\n    return this.modelConfig;\n  }\n\n  async predict(input: unknown, params: OcrRuntimeParamsInput = {}): Promise<OcrResult[]> {\n    if (!this.sourceToMat) {\n      throw new Error(\"PaddleOCR source adapter is not configured.\");\n    }\n    if (!this.detModel || !this.recModel || !this.cv || !this.ort) {\n      await this.initialize();\n    }\n\n    const cv = this.cv;\n    const detModel = this.detModel;\n    const recModel = this.recModel;\n    if (!cv || !detModel || !recModel) {\n      throw new Error(\"Initialization did not complete. Call initialize() first.\");\n    }\n\n    const sources = Array.isArray(input) ? input : [input];\n    const sourceToMat = this.sourceToMat;\n    const pipelineBatchSize = Math.max(1, Math.floor(this.pipelineConfig.pipelineBatchSize) || 1);\n    const sourceBatches = chunkArray(sources, pipelineBatchSize);\n\n    const totalStart = nowMs();","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/paddleocr-js/packages/core/src/pipelines/ocr/core.ts#L181-L217","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Prefer the high-level browser entry point (e.g. the paddleocr-js browser/web package) which configures sourceToMat automatically","Or pass a sourceToMat option implementing your input type → cv.Mat conversion when constructing the runner","Check the runner was created through the intended factory rather than new OcrPipelineRunner(...)"],"exampleFix":"// before\nconst runner = new OcrPipelineRunner(coreOpts); // no sourceToMat\nawait runner.predict(imageUrl); // throws\n\n// after\nconst runner = new OcrPipelineRunner({ ...coreOpts, sourceToMat: browserSourceToMat });\nawait runner.predict(imageUrl);","handlingStrategy":"validation","validationCode":"// Coarse check: the runner exposes no public sourceToMat, so validate construction instead\nif (!(\"sourceToMat\" in runnerOptions) && !usedHighLevelFactory) {\n  throw new Error(\"No source adapter configured — pass sourceToMat or use the browser entry point\");\n}","typeGuard":"function hasSourceAdapter(runner: { sourceToMat?: unknown }): boolean {\n  return typeof runner.sourceToMat === \"function\";\n}","tryCatchPattern":"try { await runner.predict(input); } catch (e) {\n  if (e instanceof Error && /source adapter is not configured/.test(e.message)) {\n    // construct via the browser wrapper or supply sourceToMat, then retry\n  } else throw e;\n}","preventionTips":["Construct runners through the official browser/high-level API, not the core class directly","If you build the core yourself, always pass a sourceToMat that handles your input types","Smoke-test predict() with one image immediately after setup to catch missing adapters early"],"tags":["paddleocr","adapter","configuration","lifecycle","browser"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}