{"record":{"id":"4a24a6bd100614c4","repo":"Hmbown/CodeWhale","slug":"checksum-manifest-is-missing-assetname-from","errorCode":null,"errorMessage":"Checksum manifest is missing ${assetName}${from}","messagePattern":"Checksum manifest is missing (.+?)(.+?)","errorType":"exception","errorClass":"NonRetryableError","httpStatus":null,"severity":"error","filePath":"npm/codewhale/scripts/install.js","lineNumber":1178,"sourceCode":"    const match = trimmed.match(/^([a-fA-F0-9]{64})\\s+\\*?(.+)$/);\n    if (!match) {\n      throw new NonRetryableError(`Invalid checksum manifest line: ${trimmed}`);\n    }\n    checksums.set(match[2], match[1].toLowerCase());\n  }\n  return checksums;\n}\n\nasync function sha256File(filePath) {\n  const content = await readFile(filePath);\n  return crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\nasync function verifyChecksum(filePath, assetName, checksums, sourceLabel) {\n  const expected = checksums.get(assetName);\n  if (!expected) {\n    const from = sourceLabel ? ` from ${sourceLabel}` : \"\";\n    throw new NonRetryableError(`Checksum manifest is missing ${assetName}${from}`);\n  }\n  const actual = await sha256File(filePath);\n  if (actual !== expected) {\n    // Bytes are corrupted; another fetch is unlikely to help without a fix\n    // upstream. Mark non-retryable. Never mix a locked source's bytes with\n    // another source's manifest.\n    const from = sourceLabel ? ` from ${sourceLabel}` : \"\";\n    throw new NonRetryableError(\n      `Checksum mismatch for ${assetName}${from}: expected ${expected}, got ${actual}`,\n    );\n  }\n}\n\nasync function checksumMatches(filePath, assetName, checksums) {\n  const expected = checksums.get(assetName);\n  if (!expected) {\n    throw new NonRetryableError(`Checksum manifest is missing ${assetName}`);\n  }","sourceCodeStart":1160,"sourceCodeEnd":1196,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/npm/codewhale/scripts/install.js#L1160-L1196","documentation":"`verifyChecksum` looks up the downloaded asset's name in the parsed checksum map before hashing. If the manifest does not contain an entry for that asset, verification cannot proceed and the installer throws this NonRetryableError (the `from` suffix names the source/manifest origin). This is a data-integrity guard: the installer never verifies an asset it has no published digest for.","triggerScenarios":"Downloading an asset (e.g. codewhale-linux-x64.tar.gz) whose name is absent from the fetched manifest — version skew between the manifest URL and the asset URL, an asset renamed upstream, or a mirror serving a stale SHA256SUMS.","commonSituations":"A pinned manifest from an older release while the resolver picked a newer asset name; mirrors that regenerate assets without updating SHA256SUMS; custom CODEWHALE_RELEASE_BASE_URL with a partial manifest.","solutions":["Make the manifest and asset come from the same release/version — align CODEWHALE_RELEASE_BASE_URL paths or clear the locked source.","Re-run the install so a fresh manifest is fetched for the current version.","If you own the mirror, regenerate SHA256SUMS to include all current asset names.","Check for an installer/version upgrade where the asset naming matches the available manifests."],"exampleFix":"// before (locked manifest URL from v1.2 while assets are v1.3)\nCODEWHALE_RELEASE_BASE_URL=https://mirror.example.com/codewhale/v1.2\n// after\nCODEWHALE_RELEASE_BASE_URL=https://mirror.example.com/codewhale/v1.3","handlingStrategy":"validation","validationCode":"const expected = checksums.get(assetName);\nif (!expected) throw new Error(`Manifest does not list ${assetName}; align manifest and asset versions.`);","typeGuard":null,"tryCatchPattern":"try {\n  await install();\n} catch (err) {\n  if (err.message.startsWith('Checksum manifest is missing')) {\n    // re-fetch a manifest for the same version as the assets\n  } else throw err;\n}","preventionTips":["Pin asset URL and manifest URL to the same release/version.","Regenerate mirror manifests whenever assets change.","Never mix a locked source's assets with another source's manifest."],"tags":["npm","installer","checksum","manifest","integrity"],"backgroundTag":"checksum-mismatch","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}