SubtitleEdit/subtitleedit · error · InvalidOperationException
Failed to start tesseract process.
Error message
Failed to start tesseract process.
What it means
Thrown when Process.Start(psi) returns null while trying to launch the Tesseract binary. On .NET Process.Start only returns null under UseShellExecute=true with a document URL; here UseShellExecute is false, so in practice this fires when the resolved ExecutablePath is invalid/deleted between Detect() and the call, or on platform edge cases.
Source
Thrown at src/seconv/Core/TesseractOcrEngine.cs:91
using (var image = SKImage.FromBitmap(prepped))
using (var data = image.Encode(SKEncodedImageFormat.Png, 90))
using (var fs = File.Create(pngPath))
{
data.SaveTo(fs);
}
var psi = new ProcessStartInfo(ExecutablePath)
{
ArgumentList = { pngPath, "stdout", "-l", Language, "--psm", "6" },
RedirectStandardOutput = true,
RedirectStandardError = true,
StandardOutputEncoding = System.Text.Encoding.UTF8,
StandardErrorEncoding = System.Text.Encoding.UTF8,
UseShellExecute = false,
CreateNoWindow = true,
};
using var proc = Process.Start(psi)
?? throw new InvalidOperationException("Failed to start tesseract process.");
// Drain stderr concurrently — Tesseract emits warnings to stderr, and reading
// stdout to completion while stderr fills the pipe buffer would deadlock.
var stderrTask = proc.StandardError.ReadToEndAsync();
var stdout = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
if (proc.ExitCode != 0)
{
var err = stderrTask.GetAwaiter().GetResult();
throw new InvalidOperationException($"Tesseract exited with code {proc.ExitCode}: {err}");
}
return stdout.Trim();
}
finally
{
try { File.Delete(pngPath); } catch { /* best-effort */ }
prepped.Dispose();
}
}View on GitHub (pinned to 17a9f07487)
Solutions
- Re-run TesseractOcrEngine.Detect() / `which tesseract` at the time of failure to confirm the binary still exists and is executable.
- Reinstall Tesseract and recreate the engine (Create caches the path).
- Check filesystem permissions and that ExecutablePath is a real executable, not a directory or symlink to nothing.
Example fix
// guard before recognising
if (!File.Exists(engine.ExecutablePath)) {
throw new InvalidOperationException("Tesseract binary vanished: " + engine.ExecutablePath);
} Defensive patterns
Strategy: validation
Validate before calling
if (!File.Exists(engine.ExecutablePath))
throw new InvalidOperationException("Tesseract binary missing: " + engine.ExecutablePath); Type guard
static bool IsExecutablePresent(string path) => File.Exists(path);
Try / catch
null
Prevention
- Create the OCR engine lazily right before recognition, not at process start.
- Re-detect the binary if long-lived processes may see it removed.
- Log ExecutablePath on startup for diagnosability.
When it happens
Trigger: Tesseract was found by Detect() (so error 147 did not fire) but Process.Start(ExecutablePath) returns null at recognition time — e.g. the binary was removed, the path is a broken symlink, or an AV/quarantine deleted it.
Common situations: Tesseract uninstalled or moved after engine creation; sandboxing that blocks exec; race with a package manager removing tesseract; path points to a non-executable.
Related errors
- Tesseract not found on PATH. Install it from https://tessera
- Tesseract exited with code {proc.ExitCode}: {err}
- No image handler for format '{options.Format}'
- Could not find a free output filename for: {baseName}
- Subtitle file not found: {filePath}
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/a51e06631e7ade74.
Report an issue: GitHub.