CloakHQ/CloakBrowser · error · InvalidOperationException

Pro download completed but binary not found at: {p}

Error message

Pro download completed but binary not found at: {p}

What it means

Thrown after the Pro Chromium download routine reports success but the expected binary path does not exist on disk. It indicates the download/extraction pipeline silently failed or extracted to an unexpected location. The library treats it as a hard integrity check on the managed Pro binary.

Source

Thrown at dotnet/src/CloakBrowser/Download.cs:1240

        string licenseKey, CancellationToken ct = default, string? releaseChannel = null)
    {
        var latest = License.GetProLatestVersion(releaseChannel);
        if (string.IsNullOrEmpty(latest)) return null;

        var effective = Config.GetEffectiveVersion(pro: true, releaseChannel: releaseChannel);
        if (effective != null && !Config.VersionNewer(latest, effective) && ProBinaryReady(effective))
        {
            // Already on the latest cached Pro build.
            return null;
        }

        if (!ProBinaryReady(latest))
        {
            CloakLog.Info("Downloading Pro Chromium {0}...", latest);
            await DownloadProBinaryAsync(latest, licenseKey, ct).ConfigureAwait(false);
            var p = Config.GetBinaryPath(latest, pro: true);
            if (!File.Exists(p))
                throw new InvalidOperationException($"Pro download completed but binary not found at: {p}");
        }

        WriteProVersionMarker(latest, releaseChannel);
        return latest;
    }

    /// <summary>Synchronous convenience wrapper around <see cref="CheckForProUpdateAsync"/>.</summary>
    public static string? CheckForProUpdate(string licenseKey, string? releaseChannel = null) =>
        CheckForProUpdateAsync(licenseKey, releaseChannel: releaseChannel).GetAwaiter().GetResult();

    private static bool ShouldCheckForUpdate()
    {
        if ((Environment.GetEnvironmentVariable("CLOAKBROWSER_AUTO_UPDATE") ?? "").ToLowerInvariant() == "false")
            return false;
        if (Config.GetLocalBinaryOverride() != null) return false;
        if (Environment.GetEnvironmentVariable("CLOAKBROWSER_DOWNLOAD_URL") != null) return false;

        var checkFile = Path.Combine(Config.GetCacheDir(), ".last_update_check");

View on GitHub (pinned to d6bad5de26)

Solutions

  1. Manually clear the browser cache/download directory and retry so a fresh archive is downloaded and extracted.
  2. Check disk space and write permissions on the directory returned by Config.GetBinaryPath.
  3. Verify antivirus/quarantine exclusions for the browser cache directory, then retry.
  4. Inspect the downloaded archive layout and confirm Config.GetBinaryPath computes the same path the extractor writes to; report a bug if they diverge.

Example fix

// before
await DownloadProBinaryAsync(latest, licenseKey, ct);
var p = Config.GetBinaryPath(latest, pro: true);
if (!File.Exists(p)) throw new InvalidOperationException($"Pro download completed but binary not found at: {p}");

// after (defensive caller: pre-check and self-heal)
var p = Config.GetBinaryPath(latest, pro: true);
if (!File.Exists(p))
{
    Directory.Delete(Path.GetDirectoryName(p)!, recursive: true); // clear partial state
    await DownloadAsync(clearCache: true, ct);                    // re-download
}
p = Config.GetBinaryPath(latest, pro: true);
File.Exists(p).Should().BeTrue();
Defensive patterns

Strategy: validation

Validate before calling

var p = Config.GetBinaryPath(latestVersion, pro: true);
if (!File.Exists(p))
{
    await browser.Download.ClearCacheAsync(); // remove partial state
    await browser.Download.DownloadAsync(clearCache: true);
}

Try / catch

catch (InvalidOperationException ex) when (ex.Message.StartsWith("Pro download completed but binary not found"))
{
    await browser.Download.ClearCacheAsync();
    await browser.Download.DownloadAsync(clearCache: true); // retry once
}

Prevention

When it happens

Trigger: Calling the Pro-version ensure/download flow (Download with a license key for the Pro channel) when DownloadProBinaryAsync completes without exception but Config.GetBinaryPath(latest, pro: true) points to a missing file — e.g. archive extracted into a subdirectory, disk full, antivirus quarantine, or a mismatched version string used for the path.

Common situations: Antivirus/EDR removing the downloaded Chromium binary; insufficient disk space during extraction; changed archive layout in a new Pro release; stale Config.GetBinaryPath mapping after upgrading the package; read-only cache directory.

Related errors


AI-assisted analysis of CloakHQ/CloakBrowser@d6bad5de26 (2026-08-28). Data as JSON: /api/errors/b24b2cbce246493e. Report an issue: GitHub.