PaddlePaddle/PaddleOCR · error · Error

Assets must define at least one asset.

Error message

Assets must define at least one asset.

What it means

Thrown by normalizeAssets() when the assets object, after resolving defaults, contains zero entries. The OCR pipeline needs at least one model asset to run, so an explicitly empty assets mapping ({}) that overrides built-ins is rejected. Note Object.entries(assets || {}) also treats non-object input the same way, so undefined/empty both land here when no defaults merge in.

Source

Thrown at paddleocr-js/packages/core/src/resources/model-asset.ts:87

  if (!isObject(asset)) {
    throw new Error(`Asset "${assetName}" must be an object.`);
  }
  if (!isNonEmptyString(asset.url)) {
    throw new Error(`Asset "${assetName}" must define url.`);
  }

  return {
    url: asset.url
  };
}

export function normalizeAssets(
  assets: Record<string, unknown> | undefined
): Record<string, ModelAsset> {
  const assetEntries = Object.entries(assets || {});

  if (assetEntries.length === 0) {
    throw new Error("Assets must define at least one asset.");
  }

  return Object.fromEntries(
    assetEntries.map(([assetName, asset]) => [assetName, normalizeModelAsset(assetName, asset)])
  );
}

// --- Model loading ---

export function getModelEntryPath(slot: string): string | null {
  return MODEL_ENTRY_PATHS[slot] || null;
}

export function assertModelResourceSlot(kind: string, slot: string, value: unknown): void {
  if (slot === "model") {
    if (!(value instanceof Uint8Array) || value.byteLength === 0) {
      throw new Error(`${kind} model requires a non-empty ${MODEL_ENTRY_PATHS.model} resource.`);
    }

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Omit the assets option entirely to use built-in defaults
  2. Provide at least one entry: assets: { det: "..." } or { det: { url } }
  3. Log the assembled config before create() to catch accidental empty objects

Example fix

// before
const ocr = await PaddleOCR.create({ assets: {} }); // throws: at least one asset required

// after
const ocr = await PaddleOCR.create({}); // use built-in default assets
Defensive patterns

Strategy: validation

Validate before calling

const assets = maybeAssets && Object.keys(maybeAssets).length > 0 ? maybeAssets : undefined;
// pass undefined (not {}) to use defaults

Type guard

function hasAssets(v: unknown): v is Record<string, unknown> {
  return typeof v === "object" && v !== null && Object.keys(v).length > 0;
}

Prevention

When it happens

Trigger: Passing assets: {} explicitly (overriding default assets); a config spread that results in an empty object; passing assets: undefined in a code path where defaults are not applied.

Common situations: Apps intending to disable a subset of models by passing an empty object instead of omitting the key; dynamic config assembly that filters out every entry.

Related errors


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