{"record":{"id":"a51e06631e7ade74","repo":"SubtitleEdit/subtitleedit","slug":"failed-to-start-tesseract-process","errorCode":null,"errorMessage":"Failed to start tesseract process.","messagePattern":"Failed to start tesseract process\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/seconv/Core/TesseractOcrEngine.cs","lineNumber":91,"sourceCode":"            using (var image = SKImage.FromBitmap(prepped))\n            using (var data = image.Encode(SKEncodedImageFormat.Png, 90))\n            using (var fs = File.Create(pngPath))\n            {\n                data.SaveTo(fs);\n            }\n\n            var psi = new ProcessStartInfo(ExecutablePath)\n            {\n                ArgumentList = { pngPath, \"stdout\", \"-l\", Language, \"--psm\", \"6\" },\n                RedirectStandardOutput = true,\n                RedirectStandardError = true,\n                StandardOutputEncoding = System.Text.Encoding.UTF8,\n                StandardErrorEncoding = System.Text.Encoding.UTF8,\n                UseShellExecute = false,\n                CreateNoWindow = true,\n            };\n            using var proc = Process.Start(psi)\n                ?? throw new InvalidOperationException(\"Failed to start tesseract process.\");\n            // Drain stderr concurrently — Tesseract emits warnings to stderr, and reading\n            // stdout to completion while stderr fills the pipe buffer would deadlock.\n            var stderrTask = proc.StandardError.ReadToEndAsync();\n            var stdout = proc.StandardOutput.ReadToEnd();\n            proc.WaitForExit();\n            if (proc.ExitCode != 0)\n            {\n                var err = stderrTask.GetAwaiter().GetResult();\n                throw new InvalidOperationException($\"Tesseract exited with code {proc.ExitCode}: {err}\");\n            }\n            return stdout.Trim();\n        }\n        finally\n        {\n            try { File.Delete(pngPath); } catch { /* best-effort */ }\n            prepped.Dispose();\n        }\n    }","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/seconv/Core/TesseractOcrEngine.cs#L73-L109","documentation":"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.","triggerScenarios":"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.","commonSituations":"Tesseract uninstalled or moved after engine creation; sandboxing that blocks exec; race with a package manager removing tesseract; path points to a non-executable.","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."],"exampleFix":"// guard before recognising\nif (!File.Exists(engine.ExecutablePath)) {\n    throw new InvalidOperationException(\"Tesseract binary vanished: \" + engine.ExecutablePath);\n}","handlingStrategy":"validation","validationCode":"if (!File.Exists(engine.ExecutablePath))\n    throw new InvalidOperationException(\"Tesseract binary missing: \" + engine.ExecutablePath);","typeGuard":"static bool IsExecutablePresent(string path) => File.Exists(path);","tryCatchPattern":"null","preventionTips":["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."],"tags":["seconv","ocr","tesseract","process-start","filesystem","race"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}