PaddlePaddle/PaddleOCR · critical

${modelRole} in inference.yml declares model_name "${declare

Error message

${modelRole} in inference.yml declares model_name "${declaredModelName}" but requested model_name is "${expectedModelName}".

What it means

validateLoadedModelName() compares the model_name declared inside the loaded model's inference.yml with the model_name the user requested. A mismatch means the directory/URL you supplied actually contains a different model than you asked for — loading it would run the wrong weights under the wrong name, so it is a hard error.

Source

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

      getSelectedModelName(baseSelection, configSelection, explicitSelection, role.selectionKey)
    ])
  ) as unknown as PipelineModelSelection;
}

export function validateLoadedModelName(
  modelRole: string,
  expectedModelName: string | null | undefined,
  configText: string
): void {
  if (!expectedModelName) {
    throw new Error(`${modelRole} model selection must define model_name.`);
  }
  const declaredModelName = extractInferenceModelName(configText);
  if (!declaredModelName) {
    throw new Error(`${modelRole} in inference.yml must define model_name.`);
  }
  if (declaredModelName !== expectedModelName) {
    throw new Error(
      `${modelRole} in inference.yml declares model_name "${declaredModelName}" but requested model_name is "${expectedModelName}".`
    );
  }
}

function resolveSelectedAsset(
  assetRole: string,
  modelRole: string,
  selectionKey: keyof PipelineModelSelection,
  baseSelection: PipelineModelSelection | null,
  configSelection: PipelineModelSelection | null,
  explicitSelection: Record<string, string | null> | null,
  configAssets: Partial<Record<string, ModelAsset>> | null,
  explicitAssets: Record<string, ModelAsset> | null
): ModelAsset | null {
  const explicitAsset = explicitAssets?.[assetRole];
  if (explicitAsset) {
    return explicitAsset;

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Make the requested *_model_name match the model_name declared in the target directory's inference.yml (the error prints both values).
  2. Update the *_model_dir to point at the directory that actually contains the requested model.
  3. Clear stale model caches if a shared cache directory mixes versions.

Example fix

// before
const ocr = await PaddleOCR.create({
  textRecognitionModelName: 'PP-OCRv5_mobile_rec',
  textRecognitionModelDir: '/models/server_rec/' // contains PP-OCRv5_server_rec
});

// after
const ocr = await PaddleOCR.create({
  textRecognitionModelName: 'PP-OCRv5_server_rec',
  textRecognitionModelDir: '/models/server_rec/'
});
Defensive patterns

Strategy: validation

Validate before calling

// Assert the yml in your model dir matches the name you request
async function assertModelDirMatches(dir: string, expectedName: string): Promise<void> {
  const yml = await (await fetch(`${dir}/inference.yml`)).text();
  const m = yml.match(/model_name\s*:\s*(\S+)/);
  if (!m || m[1] !== expectedName) {
    throw new Error(`model dir '${dir}' contains '${m?.[1] ?? 'no model_name'}', expected '${expectedName}'`);
  }
}

Try / catch

try {
  const ocr = await PaddleOCR.create(opts);
  await ocr.initialize();
} catch (e) {
  if (e instanceof Error && e.message.includes('declares model_name')) {
    // e.message shows both names: align textXModelName with the package contents
  }
  throw e;
}

Prevention

When it happens

Trigger: Setting text_detection_model_name: 'PP-OCRv5_mobile_det' but text_detection_model_dir pointing at a directory containing PP-OCRv5_server_det (or any other model); reusing a cached model path after switching model names in code.

Common situations: Renaming the requested model but forgetting to update the model_dir; two models extracted into overlapping cache directories; copy-pasting a det model path for a rec model.

Related errors


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