PaddlePaddle/PaddleOCR · error

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

Error message

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

What it means

Thrown by rec postprocess() when the recognition model's output tensor is not rank 3. CTC decoding requires the layout [N, T, C] (batch, timesteps, classes); any other rank (e.g. 2D [T*C] or 4D) cannot be decoded and the code aborts. This is the recognition-side analogue of the det dims guards and indicates a wrong or differently-exported ONNX model.

Source

Thrown at paddleocr-js/packages/core/src/models/rec.ts:294

      }
    }
    if (maxIdx > 0 && maxIdx !== prevIdx) {
      const dictIdx = maxIdx - 1;
      if (dictIdx >= 0 && dictIdx < charDict.length) {
        text += charDict[dictIdx];
        probs.push(maxVal);
      }
    }
    prevIdx = maxIdx;
  }
  const score = probs.length ? probs.reduce((a, b) => a + b, 0) / probs.length : 0;
  return { text, score };
}

function postprocess(output: Tensor, charDict: string[]): Array<{ text: string; score: number }> {
  const dims = output.dims;
  if (dims.length !== 3) {
    throw new Error(`Unexpected rec output dims: [${dims.join(", ")}]`);
  }
  const sampleCount = dims[0];
  const timeSteps = dims[1];
  const classes = dims[2];
  const data = output.data as Float32Array;
  const stride = timeSteps * classes;
  const results: Array<{ text: string; score: number }> = [];
  for (let index = 0; index < sampleCount; index += 1) {
    results.push(decodeCTCSample(data, index * stride, timeSteps, classes, charDict));
  }
  return results;
}

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Log the dims included in the message and compare to the expected [batch, timesteps, classes]
  2. Use the rec model file bundled with / referenced by this paddleocr-js version
  3. If re-exporting, keep the softmax logits output as rank 3 and do not fold decode ops into the graph
  4. Verify the config's model asset descriptor points at a CRNN/SVTR-style CTC recognition model
Defensive patterns

Strategy: try-catch

Type guard

function isCtcLogitsDims(dims: readonly number[]): dims is [number, number, number] {
  return dims.length === 3;
}

Try / catch

try { await recModel.predict(cv, crops); } catch (e) {
  if (e instanceof Error && /Unexpected rec output dims/.test(e.message)) {
    // wrong rec model or folded decode ops in the graph: use the bundled CTC rec asset
  } else throw e;
}

Prevention

When it happens

Trigger: Loading a non-CTC rec model or a classifier into the rec slot; a re-exported model whose logits were reshaped/squeezed at the graph tail; an ONNX Runtime version altering output rank for dynamic shapes.

Common situations: Mixing model versions (rec ONNX from one release with core code from another); custom export adding argmax/greedy-decode nodes into the graph so the raw logits never reach the JS side; wrong model wired via config asset descriptors.

Related errors


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