Hmbown/CodeWhale · critical · NonRetryableError

Checksum mismatch for

Error message

Checksum mismatch for ${assetName}${from}: expected ${expected}, got ${actual}

What it means

After hashing the downloaded file, `verifyChecksum` compares the actual SHA-256 with the digest from the manifest. A mismatch means the bytes on disk differ from the published artifact — the download was corrupted, truncated, or tampered with — so the installer throws a NonRetryableError and explicitly refuses to retry, since re-fetching from the same broken source will not fix it.

Solutions

  1. Delete the cached/partial download and retry from a different network (the error is non-retryable by design, so change the source, not just re-run).
  2. Switch to the official GitHub Release source (unset CODEWHALE_RELEASE_BASE_URL / CODEWHALE_USE_CNB_MIRROR).
  3. Compare the file's sha256 manually (`sha256sum <file>`) against the manifest and re-download the asset.
  4. If you operate the mirror, restore the exact published artifact bytes that match SHA256SUMS.
  5. Check proxy/AV software that may rewrite downloaded binaries.
Defensive patterns

Strategy: retry

Try / catch

try {
  await install();
} catch (err) {
  if (err.message.startsWith('Checksum mismatch for')) {
    // non-retryable by design: change source/network, purge cache, then retry once
    await purgeCache();
    await install({ source: 'official' });
  } else throw err;
}

Prevention

When it happens

Trigger: sha256File(filePath) != checksums.get(assetName) after a completed download from the release/mirror source identified by sourceLabel.

Common situations: Flaky network or proxy truncating large tarballs; a mirror serving stale or re-uploaded (bit-different) artifacts; CDN cache poisoning; disk corruption; interrupted write not caught by size checks.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/001ddf98a4c32ad1. Report an issue: GitHub.

Appendix: source

Thrown at npm/codewhale/scripts/install.js:1186

async function sha256File(filePath) {
  const content = await readFile(filePath);
  return crypto.createHash("sha256").update(content).digest("hex");
}

async function verifyChecksum(filePath, assetName, checksums, sourceLabel) {
  const expected = checksums.get(assetName);
  if (!expected) {
    const from = sourceLabel ? ` from ${sourceLabel}` : "";
    throw new NonRetryableError(`Checksum manifest is missing ${assetName}${from}`);
  }
  const actual = await sha256File(filePath);
  if (actual !== expected) {
    // Bytes are corrupted; another fetch is unlikely to help without a fix
    // upstream. Mark non-retryable. Never mix a locked source's bytes with
    // another source's manifest.
    const from = sourceLabel ? ` from ${sourceLabel}` : "";
    throw new NonRetryableError(
      `Checksum mismatch for ${assetName}${from}: expected ${expected}, got ${actual}`,
    );
  }
}

async function checksumMatches(filePath, assetName, checksums) {
  const expected = checksums.get(assetName);
  if (!expected) {
    throw new NonRetryableError(`Checksum manifest is missing ${assetName}`);
  }
  const actual = await sha256File(filePath);
  return actual === expected;
}

function formatSourceReceipt(source, version) {
  return [
    `source=${source.id}`,
    `label=${source.label}`,

View on GitHub (pinned to 433685b202)