PaddlePaddle/PaddleOCR · error
${modulePath}.model_dir must be null or an asset descriptor
Error message
${modulePath}.model_dir must be null or an asset descriptor object in browser usage. What it means
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.
Source
Thrown at paddleocr-js/packages/core/src/pipelines/ocr/config.ts:124
`${modulePath}.model_name must be provided when ${modulePath}.model_dir is set.`
);
}
}
function getModuleAsset(
assetName: string,
modulePath: string,
moduleConfig: YamlObject | null
): ModelAsset | null {
if (moduleConfig?.model_dir == null) {
return null;
}
if (isPlainObject(moduleConfig.model_dir)) {
const asset = normalizeModelAsset(assetName, moduleConfig.model_dir);
validateModuleAsset(modulePath, getModuleModelName(moduleConfig));
return asset;
}
throw new Error(
`${modulePath}.model_dir must be null or an asset descriptor object in browser usage.`
);
}
export function parseOcrPipelineConfigText(text: string): YamlObject {
return parsePipelineConfigInput(text);
}
export function normalizeOcrPipelineConfig(input: unknown): NormalizedPipelineConfig {
const config = parsePipelineConfigInput(input);
const pipelineName = (config.pipeline_name as string | undefined) ?? SUPPORTED_PIPELINE_NAME;
if (pipelineName !== SUPPORTED_PIPELINE_NAME) {
throw new Error(
`Unsupported pipeline_name "${pipelineName}". PaddleOCR.js currently supports only "${SUPPORTED_PIPELINE_NAME}".`
);
}
View on GitHub (pinned to 2661c7c0ef)
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
Example fix
# before
TextDetection:
model_name: PP-OCRv5_mobile_det
model_dir: "./local_models/det"
# after
TextDetection:
model_name: PP-OCRv5_mobile_det
model_dir:
url: "https://your-cdn/models/det.onnx" Defensive patterns
Strategy: validation
Validate before calling
const dir = mod.model_dir;
if (dir != null && typeof dir !== "object") {
throw new Error(`${modulePath}.model_dir must be an asset descriptor object (browser) — got ${typeof dir}`);
} Type guard
function isBrowserModelDir(dir: unknown): dir is null | Record<string, unknown> {
return dir == null || (typeof dir === "object" && !Array.isArray(dir));
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- RecResizeImg.image_shape is required in rec inference.yml
- OCR pipeline config text must decode to an object.
- OCR pipeline config must be an object or YAML text.
- ${modulePath}.model_name must be provided when ${modulePath}
- Unsupported pipeline_name "${pipelineName}". PaddleOCR.js cu
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/22d9ec8216d1c841.
Report an issue: GitHub.