{"record":{"id":"ea07257fbe44205e","repo":"babalae/better-genshin-impact","slug":"unable-to-getlabelbyindex-index-i-out-of-range","errorCode":null,"errorMessage":"Unable to GetLabelByIndex: index {i} out of range {labels.Count}, OCR model or labels not matched?","messagePattern":"Unable to GetLabelByIndex: index (.+?) out of range (.+?), OCR model or labels not matched\\?","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/Core/Recognition/OCR/Engine/OcrUtils.cs","lineNumber":178,"sourceCode":"        return new DenseTensor<float>(\n            tensorMemoryOwner.Memory[..(int)total],\n            new[] { 1, resizedImage.Channels(), resizedImage.Rows, resizedImage.Cols }\n        );\n    }\n\n    /// <summary>\n    ///     Gets a label by its index.\n    /// </summary>\n    /// <param name=\"i\">The index of the label.</param>\n    /// <param name=\"labels\">The labels to search for the index.</param>\n    /// <returns>The label at the specified index.</returns>\n    public static string GetLabelByIndex(int i, IReadOnlyList<string> labels)\n    {\n        return i switch\n        {\n            var x when x > 0 && x <= labels.Count => labels[x - 1],\n            var x when x == labels.Count + 1 => \" \",\n            _ => throw new Exception(\n                $\"Unable to GetLabelByIndex: index {i} out of range {labels.Count}, OCR model or labels not matched?\")\n        };\n    }\n\n    public static Mat Tensor2Mat(Tensor<float> tensor)\n    {\n        var dimensions = tensor.Dimensions;\n        if (dimensions.Length != 4 || dimensions[0] != 1 || dimensions[1] != 1)\n            throw new ArgumentException($\"wrong tensor shape: {string.Join(\",\", dimensions.ToArray())}\");\n        if (tensor is not DenseTensor<float> denseTensor)\n            return Mat.FromPixelData(dimensions[2], dimensions[3], MatType.CV_32FC1, tensor.ToArray());\n        var mat = new Mat(new Size(dimensions[3], dimensions[2]), MatType.CV_32FC1);\n        denseTensor.Buffer.Span.CopyTo(mat.AsSpan<float>());\n        return mat;\n    }\n}","sourceCodeStart":160,"sourceCodeEnd":194,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/Core/Recognition/OCR/Engine/OcrUtils.cs#L160-L194","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Re-download the complete, version-matched model + label files for the selected PaddleOcrModelType.","Verify the labels file line count matches the model's vocabulary size.","Select a different PaddleOcrModelConfig whose assets are intact."],"exampleFix":"// no code fix — this is an asset mismatch. Ensure model and label files match:\n// models/paddle/v5/det.onnx + rec.onnx MUST ship with the matching dict.txt\n// re-download the model bundle for the configured PaddleOcrModelType.","handlingStrategy":"validation","validationCode":"// defensive bounds check before relying on the result\nstring label;\ntry { label = OcrUtils.GetLabelByIndex(i, labels); }\ncatch (Exception) { label = string.Empty; /* model/labels mismatch — log and re-download assets */ }","typeGuard":"static bool IsIndexInVocab(int i, int labelCount) => i > 0 && i <= labelCount + 1;","tryCatchPattern":"try { return OcrUtils.GetLabelByIndex(i, labels); }\ncatch (Exception ex)\n{\n    logger.LogError(ex, \"OCR model/labels mismatch (index {I}, vocab {N})\", i, labels.Count);\n    return string.Empty;\n}","preventionTips":["Ship model and its matching label/dict file together as a versioned bundle.","Verify labels file line count equals the model vocabulary size at startup.","Re-download assets if the mismatch recurs."],"tags":["ocr","paddleocr","onnx","model-mismatch","assets"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}