Yeachan-Heo/oh-my-codex · critical · Error
[native-assets] checksum mismatch for ${asset.archive}
Error message
[native-assets] checksum mismatch for ${asset.archive} What it means
The SHA-256 of the downloaded archive does not match asset.sha256 from the release manifest. This is the cryptographic integrity gate; a mismatch means the bytes are not what the publisher shipped (corruption, MITM on plain HTTP, or a mismatched manifest/asset pair).
Source
Thrown at src/cli/native-assets.ts:739
const asset = assets[index]!;
const archivePath = join(tempRoot, asset.archive);
const cachedBinaryPath = resolveCachedNativeBinaryPath(
product,
version,
platform,
arch,
env,
inferNativeAssetLibc(asset),
);
try {
await downloadFile(asset.download_url, archivePath);
const archiveStat = await stat(archivePath);
if (typeof asset.size === 'number' && asset.size > 0 && archiveStat.size !== asset.size) {
throw new Error(`[native-assets] downloaded archive size mismatch for ${asset.archive}`);
}
const digest = await sha256ForFile(archivePath);
if (digest !== asset.sha256) {
throw new Error(`[native-assets] checksum mismatch for ${asset.archive}`);
}
const archiveEntries = await inspectNativeArchive(archivePath);
const archiveBinary = selectNativeArchiveBinary(archiveEntries, asset.binary_path);
await writeSelectedNativeArchiveMember(archivePath, archiveBinary.path, extractedBinaryPath);
const published = await publishManagedNativeBinary(extractedBinaryPath, cachedBinaryPath, platform, env);
if (published) return published;
throw new Error(`[native-assets] cache publication verification failed for ${cachedBinaryPath}`);
} catch (error) {
if (index < assets.length - 1 && isUnavailableArchiveError(error)) {
await rm(archivePath, { force: true });
await rm(extractedBinaryPath, { force: true });
continue;
}
throw error;
}
}View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Re-download from the official GitHub release URL over HTTPS.
- Verify manually: sha256sum <archive> vs the manifest value to distinguish corruption from a bad release.
- If consistently mismatched from the official URL, the release assets are bad — pin a known-good version or re-publish.
Defensive patterns
Strategy: fallback
Validate before calling
import { createHash } from 'node:crypto';
import { readFile } from 'node:fs/promises';
async function sha256(p: string): Promise<string> { return createHash('sha256').update(await readFile(p)).digest('hex'); }
// compare against manifest asset.sha256 before trusting a mirrored archive Try / catch
try { await hydrateNativeBinary(); } catch (e) { if (/checksum mismatch for/.test(String(e))) { /* fetch from official HTTPS release URL; if it still fails, the release is bad — pin another version */ } throw e; } Prevention
- Only download over HTTPS from official release hosts
- Pin versions whose releases are verified
- Report persistent mismatches — never bypass the check
When it happens
Trigger: hydrateNativeBinary when sha256ForFile(archivePath) !== asset.sha256 — corrupted transfer, mirror serving different bytes, or manifest checksums regenerated against different asset builds.
Common situations: HTTP (not HTTPS) mirrors tampering with artifacts; interrupted downloads resumed incorrectly; release automation uploading assets after writing the manifest.
Related errors
- [native-assets] temporary checksum verification failed
- [native-assets] downloaded archive size mismatch for ${asset
- Unknown adapt target: ${target}
- native_agent_canonical_invalid
- invalid auth slot name: use 1-64 letters, numbers, '.', '_'
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/f9f8abbda1377b58.
Report an issue: GitHub.