can1357/oh-my-pi · error · Error

Browser archive did not contain its expected executable: ${e

Error message

Browser archive did not contain its expected executable: ${executablePath}

What it means

After downloading and unpacking the Chrome archive into a staging dir and moving it into place, install() verifies the expected executable exists at computeExecutablePath's location; if it does not, the archive content did not match the expected layout (or extraction failed silently) and this Error is thrown. Staging artifacts are cleaned up before throwing.

Source

Thrown at packages/utils/src/browsers.ts:268

	const stagingPath = path.join(options.cacheDir, `.browser-${nonce}`);
	try {
		await downloadArchive(
			getDownloadUrl(options.browser, platform, options.buildId, options.baseUrl),
			archivePath,
			options.downloadProgressCallback,
		);
		await extractArchive(archivePath, stagingPath, { limits: BROWSER_ARCHIVE_LIMITS });
		await fsp.mkdir(path.dirname(installPath), { recursive: true });
		await fsp.rm(installPath, { recursive: true, force: true });
		await fsp.rename(stagingPath, installPath);
	} finally {
		await Promise.all([
			fsp.rm(archivePath, { force: true }).catch(() => {}),
			fsp.rm(stagingPath, { recursive: true, force: true }).catch(() => {}),
		]);
	}
	if (!(await pathExists(executablePath)))
		throw new Error(`Browser archive did not contain its expected executable: ${executablePath}`);
	return { browser: options.browser, buildId: options.buildId, platform, path: installPath, executablePath };
}

function chromeChannelName(tag: string): string | undefined {
	switch (tag) {
		case BrowserTag.STABLE:
			return "Stable";
		case BrowserTag.BETA:
			return "Beta";
		case BrowserTag.DEV:
			return "Dev";
		case BrowserTag.CANARY:
			return "Canary";
		default:
			return undefined;
	}
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Delete the partial install dir under cacheDir and retry the install.
  2. Verify the download by inspecting the archive (list entries) to confirm the expected chrome-* folder layout exists.
  3. Check disk space and directory permissions in cacheDir.
  4. Check antivirus/quarantine logs if the binary vanished post-extract.
  5. Try a different buildId (pin an exact version) in case the specific build's layout differs.

Example fix

// before
const b = await install({ browser: Browser.CHROME, buildId, cacheDir });
// after
try {
  const b = await install({ browser: Browser.CHROME, buildId, cacheDir });
} catch (err) {
  if (String(err).includes('did not contain its expected executable')) {
    await fsp.rm(path.join(cacheDir, 'chrome', buildId), { recursive: true, force: true });
    // retry with a pinned known-good buildId
  }
  throw err;
}
Defensive patterns

Strategy: retry

Validate before calling

// preflight: confirm the build's archive exists and check disk space
const head = await fetch(`https://storage.googleapis.com/chrome-for-testing-public/${buildId}/linux64/chrome-linux64.zip`, { method: 'HEAD' });
if (!head.ok) throw new Error(`No archive for ${buildId}; pick another buildId`);
const stat = await fsp.statfs?.(cacheDir).catch(() => null);
// ensure enough free space before downloading

Type guard

null

Try / catch

let installed;
for (let attempt = 0; attempt < 2 && !installed; attempt++) {
  try {
    installed = await install({ browser: Browser.CHROME, buildId, cacheDir });
  } catch (err) {
    if (/did not contain its expected executable/.test(String(err)) && attempt === 0) {
      await fsp.rm(path.join(cacheDir, 'chrome', buildId), { recursive: true, force: true }); // clear partial install, retry
      continue;
    }
    throw err;
  }
}

Prevention

When it happens

Trigger: install() completes the download+extract flow but pathExists(executablePath) is false — e.g. the upstream archive layout changed (folder renamed), extraction skipped/failed for a member, partial/corrupt archive extracted without error, or an antivirus removed the binary.

Common situations: Google renaming chrome-linux64/ to something else in a new build; disk-full or permission errors during extraction swallowed by cleanup; corrupted download behind a proxy that returned an HTML error page with 200; security software quarantining chrome.exe.

Related errors


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