PaddlePaddle/PaddleOCR · error

Unexpected det output dims: [${od.join(", ")}]

Error message

Unexpected det output dims: [${od.join(", ")}]

What it means

Thrown by postprocess() in the det pipeline: the full batched output tensor must be rank 3 or 4 so the code can extract batch (N), height, and width axes. A different rank means the ONNX graph output layout is incompatible with this postprocessor — effectively the same failure class as the getDetMap guard, but on the batched path before per-sample slicing.

Source

Thrown at paddleocr-js/packages/core/src/models/det.ts:428

  const base = batchDetOutputPlaneOffset(dims, batchIndex);
  const out = new Float32Array(cropOh * cropOw);
  for (let r = 0; r < cropOh; r += 1) {
    const rowStart = base + r * owFull;
    out.set(data.subarray(rowStart, rowStart + cropOw), r * cropOw);
  }
  return new ort.Tensor("float32", out, [1, 1, cropOh, cropOw]);
}

function postprocess(
  context: DetRunContext,
  fullOutput: Tensor,
  preps: DetPreprocessResult[],
  params: InternalDetParams
): InternalDetBatchItem[] {
  const { cv, ort, config } = context;
  const od = fullOutput.dims;
  if (od.length !== 3 && od.length !== 4) {
    throw new Error(`Unexpected det output dims: [${od.join(", ")}]`);
  }
  const ohFull = od.length === 4 ? od[2] : od[1];
  const owFull = od.length === 4 ? od[3] : od[2];
  const nOut = od.length === 4 ? od[0] : preps.length === 1 ? 1 : od[0];
  if (nOut !== preps.length) {
    throw new Error(
      `Detection batch output N=${String(nOut)} does not match input batch ${String(preps.length)}`
    );
  }

  const maxH = Math.max(...preps.map((p) => p.dstH));
  const maxW = Math.max(...preps.map((p) => p.dstW));

  const items: InternalDetBatchItem[] = [];
  for (let i = 0; i < preps.length; i += 1) {
    const prep = preps[i];
    const { cropOh, cropOw } = detFeatureCropDims(prep.dstH, prep.dstW, maxH, maxW, ohFull, owFull);
    const planeTensor = sliceBatchedDetOutputPlane(

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Restore the det model ONNX file that matches this package version and retry
  2. If a custom export is required, keep the output as [N, C, H, W] (rank 4)
  3. Print the offending dims (already included in the message) and check whether N/H/W were collapsed during export
  4. Confirm no pre/post transform node (reshape/squeeze) was added to the model graph tail
Defensive patterns

Strategy: try-catch

Type guard

function isBatchedDetDims(dims: readonly number[]): boolean {
  return dims.length === 3 || dims.length === 4;
}

Try / catch

try { await detModel.predict(cv, mats); } catch (e) {
  if (e instanceof Error && /Unexpected det output dims/.test(e.message)) {
    // wrong det model or altered export: restore matching model asset
  } else throw e;
}

Prevention

When it happens

Trigger: Running batched detection inference where the model's output tensor is rank 2 (e.g. [N, H*W]) or rank 5; caused by a custom-exported det model, a wrong model file, or an ORT version that reshapes outputs differently.

Common situations: Replacing the bundled det ONNX with a re-export using different opset/export options; using a dynamic-shape model whose output collapses dims at batch=1; version drift between paddleocr-js core and the model files.

Related errors


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