SubtitleEdit/subtitleedit · error · Exception
Paddle OCR failed: {paddleOcr.Error}
Error message
Paddle OCR failed: {paddleOcr.Error} What it means
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.
Source
Thrown at src/ui/Features/Video/VideoOcr/VideoOcrViewModel.cs:948
if (group != null)
{
group.Text = VideoOcrLineBuilder.CleanOcrResult(p.Text);
reportProgress();
addPreviewLine(group);
}
});
// The frames are already image files on disk, so pass them by file name -
// one batch, no per-image decode/encode, memory stays flat.
var batch = ocrGroups
.Select((g, i) => new PaddleOcrBatchInput { Index = i, SourceFileName = g.RepresentativeFileName })
.ToList();
var paddleOcr = new PaddleOcr();
await paddleOcr.OcrBatch(engineType, batch, language, mode, progress, cancellationToken);
if (!string.IsNullOrEmpty(paddleOcr.Error) && ocrGroups.All(p => string.IsNullOrEmpty(p.Text)))
{
throw new Exception("Paddle OCR failed: " + paddleOcr.Error);
}
}
else if (engineType == OcrEngineType.Ollama)
{
using var ollamaOcr = new OllamaOcr(Se.Settings.Ocr.OllamaOcrTimeoutMinutes);
await RunLlmOcr(ocrGroups, group => OcrWithBitmap(group, bitmap =>
ollamaOcr.Ocr(bitmap, OllamaUrl, OllamaModel, OllamaLanguage, cancellationToken)),
() => ollamaOcr.Error, reportProgress, addPreviewLine, cancellationToken);
}
else if (engineType == OcrEngineType.Glm)
{
var glmOcr = new GlmOcr(GlmApiKey);
await RunLlmOcr(ocrGroups, group =>
glmOcr.Ocr(group.RepresentativeFileName, GlmUrl, GlmModel, GlmLanguage, cancellationToken),
() => glmOcr.Error, reportProgress, addPreviewLine, cancellationToken);
}
else if (engineType == OcrEngineType.LlamaCpp)
{View on GitHub (pinned to 17a9f07487)
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.
Example fix
// before
var paddleOcr = new PaddleOcr();
await paddleOcr.OcrBatch(engineType, batch, language, mode, progress, cancellationToken);
if (!string.IsNullOrEmpty(paddleOcr.Error) && ocrGroups.All(p => string.IsNullOrEmpty(p.Text)))
throw new Exception("Paddle OCR failed: " + paddleOcr.Error);
// after - preflight the install and include which group count failed
if (!await PaddleOcrInstallHelper.EnsureInstalled(Window!, _windowService, engineType))
throw new Exception("Paddle OCR engine is not installed.");
var paddleOcr = new PaddleOcr();
await paddleOcr.OcrBatch(engineType, batch, language, mode, progress, cancellationToken);
if (!string.IsNullOrEmpty(paddleOcr.Error) && ocrGroups.All(p => string.IsNullOrEmpty(p.Text)))
throw new Exception($"Paddle OCR failed on {batch.Count} frame(s): " + paddleOcr.Error); Defensive patterns
Strategy: validation
Validate before calling
if (!await PaddleOcrInstallHelper.EnsureInstalled(Window!, _windowService, engineType))
throw new Exception("Paddle OCR engine is not installed.");
if (SelectedPaddleLanguage is null) throw new Exception("No Paddle language selected."); Try / catch
try { await paddleOcr.OcrBatch(...); }
catch (Exception ex) when (ex.Message.StartsWith("Paddle OCR failed"))
{
SeLogger.Error(ex, "Paddle OCR batch failed: " + paddleOcr.Error);
await MessageBox.Show(Window!, Se.Language.General.Error, ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- {engine.Error}
- Could not extract the current frame - see log for the ffmpeg
- No frames were extracted from the video - see log for the ff
- {Se.Language.Ocr.CrispEmbedNotDownloaded}
- {error}
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/a4e45a6bb42a64c3.
Report an issue: GitHub.