can1357/oh-my-pi · error · Error

Download failed: ${response.statusText}

Error message

Download failed: ${response.statusText}

What it means

Thrown by downloadVerifiedBinary when the binary download response is either not ok (non-2xx after redirects) or has no body. The updater cannot stream a file to disk without a response body, and any non-2xx status means the asset was not delivered. The statusText is included for diagnosis.

Source

Thrown at packages/coding-agent/src/cli/update-cli.ts:312

export async function downloadVerifiedBinary(options: VerifiedBinaryDownloadOptions): Promise<void> {
	const fetchImpl = options.fetchImpl ?? fetch;
	await unlinkIfExists(options.targetPath);

	let response: Response;
	try {
		response = await fetchImpl(options.url, {
			redirect: "follow",
			signal: withTimeoutSignal(BINARY_DOWNLOAD_TIMEOUT_MS),
		});
	} catch (err) {
		if (isTimeoutError(err)) {
			throw new Error("Timed out downloading release binary after 15 minutes", { cause: err });
		}
		if (isUnsupportedProxyError(err)) throw new Error(unsupportedProxyMessage(), { cause: err });
		throw err;
	}
	if (!response.ok || !response.body) {
		throw new Error(`Download failed: ${response.statusText}`);
	}

	const hash = createHash("sha256");
	let size = 0;
	const verifier = new Transform({
		transform(chunk, _encoding, callback) {
			size += chunk.byteLength;
			if (size > options.expectedSize) {
				callback(
					new Error(
						`Downloaded binary size mismatch: expected ${options.expectedSize} bytes, received at least ${size}`,
					),
				);
				return;
			}
			hash.update(chunk);
			callback(null, chunk);
		},

View on GitHub (pinned to 9690622007)

Solutions

  1. Retry the update — CDN 5xx errors are usually transient.
  2. Verify the asset URL exists by opening it (or `curl -I`) — if 404, wait for the release to be (re)published.
  3. Bypass suspicious proxies with `env -u HTTPS_PROXY omp update` to rule out body-stripping middleboxes.
  4. Install manually from the GitHub releases page if the asset is persistently unavailable.

Example fix

// before: corporate proxy strips response bodies
$ HTTPS_PROXY=http://corpx-proxy:3128 omp update
// Error: Download failed: 
// after: bypass proxy for github
$ env -u HTTPS_PROXY omp update
Defensive patterns

Strategy: retry

Validate before calling

const head = await fetch(assetUrl, { method: "HEAD" });
if (!head.ok) throw new Error(`Asset unavailable: ${head.status}; fix release/channel before updating`);

Type guard

function isDownloadFailed(err: unknown): boolean {
  return err instanceof Error && err.message.startsWith("Download failed:");
}

Try / catch

try {
  await runUpdate();
} catch (err) {
  if (isDownloadFailed(err) && /5\d\d| /.test(err.message)) {
    await Bun.sleep(10_000);
    return runUpdate(); // transient CDN error
  }
  throw err;
}

Prevention

When it happens

Trigger: The release asset URL returns 404 (asset removed or tag deleted), 403 (asset marked private / download quota), or 5xx from the CDN; or response.body is null despite a 2xx (rare opaque/redirect edge case).

Common situations: A canary release was deleted moments after metadata was fetched; GitHub's release-assets CDN returning transient 5xx; a proxy intercepting and stripping the body; repository made private between metadata fetch and download.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/7e881647f0cae9bc. Report an issue: GitHub.