{"record":{"id":"ab299d85ff751150","repo":"PaddlePaddle/PaddleOCR","slug":"modelrole-model-selection-must-define-model-nam","errorCode":null,"errorMessage":"${modelRole} model selection must define model_name.","messagePattern":"(.+?) model selection must define model_name\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"paddleocr-js/packages/core/src/pipelines/ocr/shared.ts","lineNumber":399,"sourceCode":"  baseSelection: PipelineModelSelection | null,\n  configSelection: PipelineModelSelection | null,\n  explicitSelection: Record<string, string | null> | null\n): PipelineModelSelection {\n  return Object.fromEntries(\n    OCR_MODEL_ROLES.map((role) => [\n      role.selectionKey,\n      getSelectedModelName(baseSelection, configSelection, explicitSelection, role.selectionKey)\n    ])\n  ) as unknown as PipelineModelSelection;\n}\n\nexport function validateLoadedModelName(\n  modelRole: string,\n  expectedModelName: string | null | undefined,\n  configText: string\n): void {\n  if (!expectedModelName) {\n    throw new Error(`${modelRole} model selection must define model_name.`);\n  }\n  const declaredModelName = extractInferenceModelName(configText);\n  if (!declaredModelName) {\n    throw new Error(`${modelRole} in inference.yml must define model_name.`);\n  }\n  if (declaredModelName !== expectedModelName) {\n    throw new Error(\n      `${modelRole} in inference.yml declares model_name \"${declaredModelName}\" but requested model_name is \"${expectedModelName}\".`\n    );\n  }\n}\n\nfunction resolveSelectedAsset(\n  assetRole: string,\n  modelRole: string,\n  selectionKey: keyof PipelineModelSelection,\n  baseSelection: PipelineModelSelection | null,\n  configSelection: PipelineModelSelection | null,","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/paddleocr-js/packages/core/src/pipelines/ocr/shared.ts#L381-L417","documentation":"validateLoadedModelName() is called after a model config (inference.yml) has been loaded to cross-check the declared model_name against what the user requested. If the caller-side expected model name is null/undefined at that point, there is nothing to validate against, which indicates the resolved model selection never defined model_name — a programming/config error, so it throws immediately.","triggerScenarios":"A pipeline code path that loads a model asset by directory/URL without a resolved model_name reaching validation, e.g. an explicit asset (model_dir) supplied without its companion *_model_name, or a custom pipelineConfig whose selection object lacks model_name.","commonSituations":"Supplying only *_model_dir options and forgetting *_model_name; hand-writing a pipelineConfig model selection block and omitting the model_name field.","solutions":["Always pair model_dir/asset options with the matching model_name option (e.g. text_detection_model_dir + text_detection_model_name).","If authoring pipelineConfig by hand, ensure each model selection entry includes model_name.","Prefer the high-level options (lang / ocrVersion) so names are filled from the default selection."],"exampleFix":"// before\nconst ocr = await PaddleOCR.create({\n  textDetectionModelDir: '/models/det/'\n});\n\n// after\nconst ocr = await PaddleOCR.create({\n  textDetectionModelName: 'PP-OCRv5_mobile_det',\n  textDetectionModelDir: '/models/det/'\n});","handlingStrategy":"validation","validationCode":"// Ensure every model_dir option is paired with its model_name before create()\nfunction validateModelPairs(o: Record<string, unknown>): string[] {\n  const pairs: [string, string][] = [\n    ['textDetectionModelDir', 'textDetectionModelName'],\n    ['textRecognitionModelDir', 'textRecognitionModelName']\n  ];\n  return pairs.filter(([dir, name]) => o[dir] !== undefined && o[name] === undefined).map(([d]) => d);\n}","typeGuard":"function hasCompleteModelSelection(o: Record<string, unknown>): boolean {\n  const detName = o.textDetectionModelName ?? o.text_detection_model_name;\n  const recName = o.textRecognitionModelName ?? o.text_recognition_model_name;\n  const detDir = o.textDetectionModelDir ?? o.text_detection_model_dir;\n  const recDir = o.textRecognitionModelDir ?? o.text_recognition_model_dir;\n  return (detDir === undefined || detName !== undefined) && (recDir === undefined || recName !== undefined);\n}","tryCatchPattern":"try {\n  const ocr = await PaddleOCR.create(opts);\n} catch (e) {\n  if (e instanceof Error && e.message.endsWith('must define model_name.')) {\n    throw new ConfigError('Model dirs require matching model names', { cause: e });\n  }\n  throw e;\n}","preventionTips":["Always configure models as (name, dir) pairs, never dir alone.","Prefer lang/ocrVersion options which fill names automatically."],"tags":["model-selection","configuration","validation"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}