SubtitleEdit/subtitleedit · error · InvalidOperationException

Failed to start yt-dlp

Error message

Failed to start yt-dlp

What it means

Thrown by DownloadVideo when Process.Start() returns false on the yt-dlp process. Start() returns false (rather than throwing) when the process is already running with the same path in some edge cases, or when the StartInfo is malformed such that the runtime declines to launch. The binary existence is checked separately (error 370), so reaching here means the file exists but would not start.

Source

Thrown at src/ui/Logic/Download/YtDlpDownloadService.cs:296

            }

            ReportLine(e.Data);
        };

        process.ErrorDataReceived += (_, e) =>
        {
            if (e.Data is null)
            {
                return;
            }

            stderrBuffer.AppendLine(e.Data);
            ReportLine(e.Data);
        };

        if (!process.Start())
        {
            throw new InvalidOperationException("Failed to start yt-dlp");
        }

        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        try
        {
            await process.WaitForExitAsync(cancellationToken);
        }
        catch (OperationCanceledException)
        {
            TryKillProcess(process);
            throw;
        }

        if (process.ExitCode != 0)
        {
            var details = stderrBuffer.ToString().Trim();

View on GitHub (pinned to 17a9f07487)

Solutions

  1. On Linux/macOS ensure the yt-dlp binary is chmod +x (the downloader should set it; verify it did).
  2. Re-run DownloadYtDlp to replace a possibly corrupted binary.
  3. Inspect process.StartInfo — FileName must equal GetFullFileName() and UseShellExecute must be false with redirection enabled.
  4. Manually run the yt-dlp binary from a shell to see the OS-level error (exec format error, permission denied).

Example fix

// before
if (!process.Start()) throw new InvalidOperationException("Failed to start yt-dlp");

// after: set the exec bit on Unix before starting, and include the OS error
if (!OperatingSystem.IsWindows())
{
    try { File.SetUnixPermissionMode(GetFullFileName(), UnixFileMode.UserExecute | UnixFileMode.UserRead); } catch { }
}
if (!process.Start())
    throw new InvalidOperationException($"Failed to start yt-dlp at {GetFullFileName()}");
Defensive patterns

Strategy: try-catch

Validate before calling

if (!OperatingSystem.IsWindows())
    try { File.SetUnixPermissionMode(YtDlpDownloadService.GetFullFileName(), UnixFileMode.UserExecute | UnixFileMode.UserRead); } catch { }

Try / catch

try { await svc.DownloadVideo(url, outPath, false, progress, ct); }
catch (InvalidOperationException ex) when (ex.Message == "Failed to start yt-dlp")
{ /* re-download to repair the binary, then retry */ await svc.DownloadYtDlp(progress, ct); }

Prevention

When it happens

Trigger: process.Start() returns false for the yt-dlp binary — typically a StartInfo problem (FileName empty/malformed, UseShellExecute conflict with redirection), a permissions issue that does not throw, or the binary present but not executable (no +x on Linux).

Common situations: On Linux the downloaded yt-dlp lacks the execute bit; on any OS a corrupted/partial binary that the OS refuses to exec; or a StartInfo misconfiguration in a fork.

Related errors


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