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

  1. Re-run TesseractOcrEngine.Detect() / `which tesseract` at the time of failure to confirm the binary still exists and is executable.
  2. Reinstall Tesseract and recreate the engine (Create caches the path).
  3. 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

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


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/a51e06631e7ade74. Report an issue: GitHub.