{"record":{"id":"22d9ec8216d1c841","repo":"PaddlePaddle/PaddleOCR","slug":"modulepath-model-dir-must-be-null-or-an-asset-d","errorCode":null,"errorMessage":"${modulePath}.model_dir must be null or an asset descriptor object in browser usage.","messagePattern":"(.+?)\\.model_dir must be null or an asset descriptor object in browser usage\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"paddleocr-js/packages/core/src/pipelines/ocr/config.ts","lineNumber":124,"sourceCode":"      `${modulePath}.model_name must be provided when ${modulePath}.model_dir is set.`\n    );\n  }\n}\n\nfunction getModuleAsset(\n  assetName: string,\n  modulePath: string,\n  moduleConfig: YamlObject | null\n): ModelAsset | null {\n  if (moduleConfig?.model_dir == null) {\n    return null;\n  }\n  if (isPlainObject(moduleConfig.model_dir)) {\n    const asset = normalizeModelAsset(assetName, moduleConfig.model_dir);\n    validateModuleAsset(modulePath, getModuleModelName(moduleConfig));\n    return asset;\n  }\n  throw new Error(\n    `${modulePath}.model_dir must be null or an asset descriptor object in browser usage.`\n  );\n}\n\nexport function parseOcrPipelineConfigText(text: string): YamlObject {\n  return parsePipelineConfigInput(text);\n}\n\nexport function normalizeOcrPipelineConfig(input: unknown): NormalizedPipelineConfig {\n  const config = parsePipelineConfigInput(input);\n  const pipelineName = (config.pipeline_name as string | undefined) ?? SUPPORTED_PIPELINE_NAME;\n\n  if (pipelineName !== SUPPORTED_PIPELINE_NAME) {\n    throw new Error(\n      `Unsupported pipeline_name \"${pipelineName}\". PaddleOCR.js currently supports only \"${SUPPORTED_PIPELINE_NAME}\".`\n    );\n  }\n","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/paddleocr-js/packages/core/src/pipelines/ocr/config.ts#L106-L142","documentation":"Thrown by getModuleAsset() when a module's model_dir is neither null nor a plain object. In browser usage model_dir cannot be a filesystem path string — it must be an asset descriptor object (url/path fields normalized by normalizeModelAsset) or absent. This guard is what converts the Node-style path convention into a hard error in the browser build.","triggerScenarios":"Config contains model_dir: \"./models/det/onnx\" or model_dir: 0/false (non-null primitives); copying a Python/Node pipeline config verbatim into browser code; YAML anchoring that yields a string where an object was expected.","commonSituations":"Porting a server-side PaddleOCR config to the browser without converting model_dir paths to asset descriptors; tutorials showing relative paths that only work in Node.","solutions":["Replace the path string with an asset descriptor object, e.g. model_dir: { url: \"https://.../det.onnx\" }","Or set model_dir to null / remove it to use the package's default model assets","Check the error's modulePath to find which module (TextDetection/TextRecognition/etc.) has the string"],"exampleFix":"# before\nTextDetection:\n  model_name: PP-OCRv5_mobile_det\n  model_dir: \"./local_models/det\"\n\n# after\nTextDetection:\n  model_name: PP-OCRv5_mobile_det\n  model_dir:\n    url: \"https://your-cdn/models/det.onnx\"","handlingStrategy":"validation","validationCode":"const dir = mod.model_dir;\nif (dir != null && typeof dir !== \"object\") {\n  throw new Error(`${modulePath}.model_dir must be an asset descriptor object (browser) — got ${typeof dir}`);\n}","typeGuard":"function isBrowserModelDir(dir: unknown): dir is null | Record<string, unknown> {\n  return dir == null || (typeof dir === \"object\" && !Array.isArray(dir));\n}","tryCatchPattern":null,"preventionTips":["In browser configs, express model_dir as { url: ... } descriptors, never path strings","Convert Python/Node configs programmatically instead of pasting them","Set model_dir to null when you want the default assets"],"tags":["paddleocr","config","browser","model-asset","validation"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}