babalae/better-genshin-impact · error · Exception

Unable to GetLabelByIndex: index {i} out of range {labels.Co

Error message

Unable to GetLabelByIndex: index {i} out of range {labels.Count}, OCR model or labels not matched?

What it means

GetLabelByIndex maps a model output index to a label string; valid indices are 1..labels.Count plus a special 'labels.Count+1' mapped to a space. Any other index (<=0, or > labels.Count+1) throws a generic Exception, signaling the ONNX model's output vocabulary and the labels file are mismatched. This is a data-integrity check, not a caller-input check.

Source

Thrown at BetterGenshinImpact/Core/Recognition/OCR/Engine/OcrUtils.cs:178

        return new DenseTensor<float>(
            tensorMemoryOwner.Memory[..(int)total],
            new[] { 1, resizedImage.Channels(), resizedImage.Rows, resizedImage.Cols }
        );
    }

    /// <summary>
    ///     Gets a label by its index.
    /// </summary>
    /// <param name="i">The index of the label.</param>
    /// <param name="labels">The labels to search for the index.</param>
    /// <returns>The label at the specified index.</returns>
    public static string GetLabelByIndex(int i, IReadOnlyList<string> labels)
    {
        return i switch
        {
            var x when x > 0 && x <= labels.Count => labels[x - 1],
            var x when x == labels.Count + 1 => " ",
            _ => throw new Exception(
                $"Unable to GetLabelByIndex: index {i} out of range {labels.Count}, OCR model or labels not matched?")
        };
    }

    public static Mat Tensor2Mat(Tensor<float> tensor)
    {
        var dimensions = tensor.Dimensions;
        if (dimensions.Length != 4 || dimensions[0] != 1 || dimensions[1] != 1)
            throw new ArgumentException($"wrong tensor shape: {string.Join(",", dimensions.ToArray())}");
        if (tensor is not DenseTensor<float> denseTensor)
            return Mat.FromPixelData(dimensions[2], dimensions[3], MatType.CV_32FC1, tensor.ToArray());
        var mat = new Mat(new Size(dimensions[3], dimensions[2]), MatType.CV_32FC1);
        denseTensor.Buffer.Span.CopyTo(mat.AsSpan<float>());
        return mat;
    }
}

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Re-download the complete, version-matched model + label files for the selected PaddleOcrModelType.
  2. Verify the labels file line count matches the model's vocabulary size.
  3. Select a different PaddleOcrModelConfig whose assets are intact.

Example fix

// no code fix — this is an asset mismatch. Ensure model and label files match:
// models/paddle/v5/det.onnx + rec.onnx MUST ship with the matching dict.txt
// re-download the model bundle for the configured PaddleOcrModelType.
Defensive patterns

Strategy: validation

Validate before calling

// defensive bounds check before relying on the result
string label;
try { label = OcrUtils.GetLabelByIndex(i, labels); }
catch (Exception) { label = string.Empty; /* model/labels mismatch — log and re-download assets */ }

Type guard

static bool IsIndexInVocab(int i, int labelCount) => i > 0 && i <= labelCount + 1;

Try / catch

try { return OcrUtils.GetLabelByIndex(i, labels); }
catch (Exception ex)
{
    logger.LogError(ex, "OCR model/labels mismatch (index {I}, vocab {N})", i, labels.Count);
    return string.Empty;
}

Prevention

When it happens

Trigger: The deployed OCR .onnx model produces an index outside the loaded labels list; labels.txt from a different model version than the .onnx; a corrupted/truncated labels file.

Common situations: Swapping a PaddleOCR model without swapping its label/dict file; partial download of model assets; model version mismatch (e.g. V5 model with V4 dict).

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/ea07257fbe44205e. Report an issue: GitHub.