{"record":{"id":"a94e050bdc11f341","repo":"SubtitleEdit/subtitleedit","slug":"yt-dlp-exited-with-code-process-exitcode","errorCode":null,"errorMessage":"yt-dlp exited with code {process.ExitCode}.","messagePattern":"yt-dlp exited with code (.+?)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/ui/Logic/Download/YtDlpDownloadService.cs","lineNumber":315,"sourceCode":"        }\n\n        process.BeginOutputReadLine();\n        process.BeginErrorReadLine();\n\n        try\n        {\n            await process.WaitForExitAsync(cancellationToken);\n        }\n        catch (OperationCanceledException)\n        {\n            TryKillProcess(process);\n            throw;\n        }\n\n        if (process.ExitCode != 0)\n        {\n            var details = stderrBuffer.ToString().Trim();\n            throw new InvalidOperationException(\n                $\"yt-dlp exited with code {process.ExitCode}.\" +\n                (string.IsNullOrEmpty(details) ? string.Empty : Environment.NewLine + details));\n        }\n\n        progress?.Report(1f);\n    }\n\n    public Task DownloadAllSubtitlesAsync(string url, string outputStem, CancellationToken cancellationToken)\n    {\n        return DownloadSubtitlesOnlyAsync(url, outputStem, autoGenerated: false, cancellationToken);\n    }\n\n    public Task DownloadAutoGeneratedSubtitlesAsync(string url, string outputStem, CancellationToken cancellationToken)\n    {\n        return DownloadSubtitlesOnlyAsync(url, outputStem, autoGenerated: true, cancellationToken);\n    }\n\n    private async Task DownloadSubtitlesOnlyAsync(string url, string outputStem, bool autoGenerated, CancellationToken cancellationToken)","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Logic/Download/YtDlpDownloadService.cs#L297-L333","documentation":"Thrown by DownloadVideo after the yt-dlp process exits with a non-zero ExitCode. The captured stderr is appended to the message so the underlying yt-dlp error (bad URL, geo-block, rate limit, missing ffmpeg, private video) is visible. Cancellation is handled separately (TryKillProcess + rethrow) so this throw is only for genuine failure exits.","triggerScenarios":"yt-dlp returns non-zero: invalid/private/region-blocked URL, YouTube rate-limiting (HTTP 429), ffmpeg not found for merging, network failure mid-download, or an outdated yt-dlp that no longer parses the site.","commonSituations":"Trying to download a private/age-restricted video without cookies; yt-dlp version is old and the extractor broke after a site change; ffmpeg missing on PATH for merge of separate audio/video.","solutions":["Read the stderr details in the exception message — it usually names the exact yt-dlp error.","Update yt-dlp (re-run DownloadYtDlp) — site-extractor breakage is the single most common cause and is fixed upstream frequently.","For private/age-restricted videos, supply a cookies.txt via yt-dlp args.","Ensure ffmpeg is installed and on PATH for post-processing merges.","Retry after a delay if the message indicates HTTP 429 rate-limiting."],"exampleFix":"// before\ncatch (InvalidOperationException ex) { log(ex.Message); }\n\n// after: surface the embedded stderr and retry on rate-limit\ntry { await _ytDlp.DownloadVideo(url, outPath, false, progress, ct); }\ncatch (InvalidOperationException ex)\n{\n    if (ex.Message.Contains(\"429\")) { await Task.Delay(TimeSpan.FromMinutes(2), ct); throw; }\n    showUser(ex.Message); // includes yt-dlp stderr\n    throw;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await svc.DownloadVideo(url, outPath, false, progress, ct); }\ncatch (InvalidOperationException ex)\n{\n    if (ex.Message.Contains(\"429\")) { await Task.Delay(TimeSpan.FromMinutes(2), ct); throw; }\n    showUser(ex.Message); throw;\n}","preventionTips":["Keep yt-dlp updated (re-run DownloadYtDlp) to avoid extractor breakage.","Ensure ffmpeg is on PATH for merging.","Supply cookies for private/age-restricted videos."],"tags":["yt-dlp","process","exit-code","network","ffmpeg"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}