Tyrrrz/YoutubeDownloader · error · InvalidOperationException
Entry '{CliFileName}' not found in the downloaded archive.
Error message
Entry '{CliFileName}' not found in the downloaded archive. What it means
Thrown inside FFmpeg.DownloadAsync after the FFmpegBin zip is downloaded and opened with ZipFile.OpenRead. The archive is readable, but zip.GetEntry(CliFileName) returns null - there is no root-level entry named exactly 'ffmpeg.exe' (Windows) or 'ffmpeg' (Unix). The library treats the entry name as a packaging contract with the upstream release.
Source
Thrown at YoutubeDownloader.Core/Downloading/FFmpeg.cs:133
IProgress<Percentage>? progress = null,
CancellationToken cancellationToken = default
)
{
var archiveFilePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + ".zip");
try
{
await Http.Client.DownloadAsync(
GetDownloadUrl(),
archiveFilePath,
progress,
cancellationToken
);
using var zip = ZipFile.OpenRead(archiveFilePath);
var entry =
zip.GetEntry(CliFileName)
?? throw new InvalidOperationException(
$"Entry '{CliFileName}' not found in the downloaded archive."
);
entry.ExtractToFile(outputFilePath, true);
// Make executable on Unix
if (!OperatingSystem.IsWindows())
{
File.SetUnixFileMode(
outputFilePath,
File.GetUnixFileMode(outputFilePath) | UnixFileMode.UserExecute
);
}
}
finally
{
// Clean up the temporary archive
if (File.Exists(archiveFilePath))View on GitHub (pinned to bbcff03951)
Solutions
- Avoid auto-download: install FFmpeg in PATH (or AppContext.BaseDirectory) so TryGetCliFilePath() returns a path and DownloadAsync is never called.
- Inspect the failing asset (unzip -l on the URL https://github.com/Tyrrrz/FFmpegBin/releases/download/<Version>/ffmpeg-<sys>-<arch>.zip); if the layout changed, pin Version to a known-good release tag or update the extraction to search Entries.
- Manually place the correct FFmpeg binary and pass ffmpegPath explicitly to the downloader.
Example fix
// before: assumes a root-level entry named CliFileName
var entry = zip.GetEntry(CliFileName)
?? throw new InvalidOperationException($"Entry '{CliFileName}' not found in the downloaded archive.");
// after: tolerate a nested or differently-cased binary
var entry = zip.GetEntry(CliFileName)
?? zip.Entries.FirstOrDefault(e => string.Equals(e.Name, CliFileName, StringComparison.Ordinal))
?? throw new InvalidOperationException($"Entry '{CliFileName}' not found in the downloaded archive."); Defensive patterns
Strategy: try-catch
Try / catch
try
{
await FFmpeg.DownloadAsync(outputPath, progress, ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("not found in the downloaded archive"))
{
// fall back to a system FFmpeg or prompt the user to install one manually
var ffmpeg = FFmpeg.TryGetCliFilePath() ?? "ffmpeg";
// pass ffmpeg explicitly to subsequent DownloadVideoAsync calls
} Prevention
- Prefer a system/provided FFmpeg over auto-download; pre-place it in CI so the download path is never exercised.
- Pin the FFmpeg Version constant to a tested FFmpegBin release tag.
- After any Version bump, verify the asset zip still contains a root-level CliFileName entry before shipping.
When it happens
Trigger: The downloaded zip's layout changed: the binary is nested under a folder (e.g. bin/ffmpeg), renamed, or the platform-specific asset was repackaged. Also reachable if the FFmpeg Version constant (FFmpeg.cs:17, currently "8.1") points to a release whose asset for the sys-arch pair follows a different convention, or a transparent proxy/CDN served a small valid zip lacking the entry.
Common situations: Tyrrrz/FFmpegBin republished a release with a different layout after a version bump; a corporate proxy substituted/stale-cached the archive; someone edited the Version constant to a tag that doesn't follow the same packaging; a truncated download that ZipFile.OpenRead tolerates but which is missing the entry.
Related errors
AI-assisted analysis of Tyrrrz/YoutubeDownloader@bbcff03951 (2026-08-13).
Data as JSON: /api/errors/3727e2e61eceb6d7.
Report an issue: GitHub.