{"record":{"id":"a4e45a6bb42a64c3","repo":"SubtitleEdit/subtitleedit","slug":"paddle-ocr-failed-paddleocr-error","errorCode":null,"errorMessage":"Paddle OCR failed: {paddleOcr.Error}","messagePattern":"Paddle OCR failed: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/ui/Features/Video/VideoOcr/VideoOcrViewModel.cs","lineNumber":948,"sourceCode":"                if (group != null)\n                {\n                    group.Text = VideoOcrLineBuilder.CleanOcrResult(p.Text);\n                    reportProgress();\n                    addPreviewLine(group);\n                }\n            });\n\n            // The frames are already image files on disk, so pass them by file name -\n            // one batch, no per-image decode/encode, memory stays flat.\n            var batch = ocrGroups\n                .Select((g, i) => new PaddleOcrBatchInput { Index = i, SourceFileName = g.RepresentativeFileName })\n                .ToList();\n\n            var paddleOcr = new PaddleOcr();\n            await paddleOcr.OcrBatch(engineType, batch, language, mode, progress, cancellationToken);\n            if (!string.IsNullOrEmpty(paddleOcr.Error) && ocrGroups.All(p => string.IsNullOrEmpty(p.Text)))\n            {\n                throw new Exception(\"Paddle OCR failed: \" + paddleOcr.Error);\n            }\n        }\n        else if (engineType == OcrEngineType.Ollama)\n        {\n            using var ollamaOcr = new OllamaOcr(Se.Settings.Ocr.OllamaOcrTimeoutMinutes);\n            await RunLlmOcr(ocrGroups, group => OcrWithBitmap(group, bitmap =>\n                    ollamaOcr.Ocr(bitmap, OllamaUrl, OllamaModel, OllamaLanguage, cancellationToken)),\n                () => ollamaOcr.Error, reportProgress, addPreviewLine, cancellationToken);\n        }\n        else if (engineType == OcrEngineType.Glm)\n        {\n            var glmOcr = new GlmOcr(GlmApiKey);\n            await RunLlmOcr(ocrGroups, group =>\n                    glmOcr.Ocr(group.RepresentativeFileName, GlmUrl, GlmModel, GlmLanguage, cancellationToken),\n                () => glmOcr.Error, reportProgress, addPreviewLine, cancellationToken);\n        }\n        else if (engineType == OcrEngineType.LlamaCpp)\n        {","sourceCodeStart":930,"sourceCodeEnd":966,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Features/Video/VideoOcr/VideoOcrViewModel.cs#L930-L966","documentation":"Thrown after PaddleOcr.OcrBatch completes: the engine set a non-empty paddleOcr.Error AND every group's Text is still empty, i.e. OCR produced no usable result and the engine self-reported a failure. It is only raised when nothing was recovered, so a partial success (some groups with text) does not throw. The exception bubbles to the StartOcr catch which logs and shows a MessageBox.","triggerScenarios":"Paddle OCR backend errored on every frame: missing/incompatible PaddleOCR model files, wrong language code, GPU/CPU mismatch, the paddle CLI/python invocation failed, or an unsupported image format fed to the batch.","commonSituations":"PaddleOCR not fully installed (model dir missing); selected language has no downloaded model; inference backend version mismatch (paddlepaddle-gpu vs CPU); frames are empty/all-black so detection fails and the engine logs an error.","solutions":["Read the embedded paddleOcr.Error text in the exception message — it carries the backend's own failure reason.","Re-run PaddleOcrInstallHelper.EnsureInstalled to (re)download the engine and its models.","Verify the selected Paddle language has its model files present and matches the installed backend version.","If using GPU, confirm the paddlepaddle-gpu build matches the CUDA version; fall back to CPU mode to isolate."],"exampleFix":"// before\nvar paddleOcr = new PaddleOcr();\nawait paddleOcr.OcrBatch(engineType, batch, language, mode, progress, cancellationToken);\nif (!string.IsNullOrEmpty(paddleOcr.Error) && ocrGroups.All(p => string.IsNullOrEmpty(p.Text)))\n    throw new Exception(\"Paddle OCR failed: \" + paddleOcr.Error);\n\n// after - preflight the install and include which group count failed\nif (!await PaddleOcrInstallHelper.EnsureInstalled(Window!, _windowService, engineType))\n    throw new Exception(\"Paddle OCR engine is not installed.\");\nvar paddleOcr = new PaddleOcr();\nawait paddleOcr.OcrBatch(engineType, batch, language, mode, progress, cancellationToken);\nif (!string.IsNullOrEmpty(paddleOcr.Error) && ocrGroups.All(p => string.IsNullOrEmpty(p.Text)))\n    throw new Exception($\"Paddle OCR failed on {batch.Count} frame(s): \" + paddleOcr.Error);","handlingStrategy":"validation","validationCode":"if (!await PaddleOcrInstallHelper.EnsureInstalled(Window!, _windowService, engineType))\n    throw new Exception(\"Paddle OCR engine is not installed.\");\nif (SelectedPaddleLanguage is null) throw new Exception(\"No Paddle language selected.\");","typeGuard":null,"tryCatchPattern":"try { await paddleOcr.OcrBatch(...); }\ncatch (Exception ex) when (ex.Message.StartsWith(\"Paddle OCR failed\"))\n{\n    SeLogger.Error(ex, \"Paddle OCR batch failed: \" + paddleOcr.Error);\n    await MessageBox.Show(Window!, Se.Language.General.Error, ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);\n}","preventionTips":["Run EnsureInstalled and verify model files for the selected language exist.","Match the paddle backend (CPU/GPU) to the installed runtime/CUDA.","Log paddleOcr.Error even on partial success to catch degrading engines."],"tags":["ocr","paddle-ocr","video-ocr","ml-model"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}