PaddlePaddle/PaddleOCR · error

text_detection_model_dir requires text_detection_model_name.

Error message

text_detection_model_dir requires text_detection_model_name.

What it means

When explicit model options are detected, getExplicitModelSelection() iterates model roles. For the text detection role, if an asset option (text_detection_model_dir or its aliases) is present but the companion name option (text_detection_model_name) is absent, it throws role.assetRequirementError, whose text is 'text_detection_model_dir requires text_detection_model_name.'. The name is required because it must match the inference.yml validation later.

Source

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

  const modelSelection: Record<string, string | null> = {};
  const assets: Record<string, ModelAsset> = {};
  let hasAnyOption = false;

  for (const role of OCR_MODEL_ROLES) {
    const modelName = readAliasedOption(options, role.nameAliases, role.nameLabel) as
      | string
      | undefined;
    const asset = readAliasedOption(options, role.assetAliases, role.assetLabel) as
      | ModelAsset
      | undefined;

    if (modelName !== undefined) {
      modelSelection[role.selectionKey] = modelName;
      hasAnyOption = true;
    }
    if (asset !== undefined) {
      if (modelName === undefined) {
        throw new Error(role.assetRequirementError);
      }
      assets[role.assetKey] = asset;
      hasAnyOption = true;
    }
  }

  if (!hasAnyOption) {
    return null;
  }

  return {
    modelSelection,
    assets
  };
}

function resolveBaseModelSelection(
  options: Record<string, unknown>,

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Add textDetectionModelName matching the model_name declared in that directory's inference.yml.
  2. Or drop the dir option to use the default hosted detection model.

Example fix

// before
const ocr = await PaddleOCR.create({ textDetectionModelDir: '/models/det/' });

// after
const ocr = await PaddleOCR.create({
  textDetectionModelName: 'PP-OCRv5_mobile_det',
  textDetectionModelDir: '/models/det/'
});
Defensive patterns

Strategy: validation

Validate before calling

if (opts.textDetectionModelDir !== undefined && (opts.textDetectionModelName ?? opts.text_detection_model_name) === undefined) {
  throw new TypeError('textDetectionModelDir requires textDetectionModelName');
}

Type guard

function isDetDirWithName(o: Record<string, unknown>): boolean {
  const dir = o.textDetectionModelDir ?? o.text_detection_model_dir;
  const name = o.textDetectionModelName ?? o.text_detection_model_name;
  return dir === undefined || typeof name === 'string';
}

Try / catch

try {
  const ocr = await PaddleOCR.create(opts);
} catch (e) {
  if (e instanceof Error && e.message === 'text_detection_model_dir requires text_detection_model_name.') {
    opts = { ...opts, textDetectionModelName: 'PP-OCRv5_mobile_det' };
    return PaddleOCR.create(opts);
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing { textDetectionModelDir: '/models/det/' } (or the snake_case alias) without textDetectionModelName to PaddleOCR.create().

Common situations: Assuming a bare directory is enough to load a self-hosted model; migrating from an API that only took paths.

Related errors


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