{"record":{"id":"3276e02700dbf626","repo":"Hmbown/CodeWhale","slug":"label-contains-an-invalid-checksum-row-trimm","errorCode":null,"errorMessage":"${label} contains an invalid checksum row: ${trimmed}","messagePattern":"(.+?) contains an invalid checksum row: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/release/assemble-release-assets.js","lineNumber":40,"sourceCode":"  ].join(\"\\n\");\n}\n\nasync function sha256(filePath) {\n  const hash = crypto.createHash(\"sha256\");\n  hash.update(await fs.readFile(filePath));\n  return hash.digest(\"hex\");\n}\n\nfunction parseChecksumManifest(content, label) {\n  const checksums = new Map();\n  for (const line of content.split(/\\r?\\n/)) {\n    const trimmed = line.trim();\n    if (!trimmed) {\n      continue;\n    }\n    const match = trimmed.match(/^([a-fA-F0-9]{64})\\s+\\*?(.+)$/);\n    if (!match) {\n      throw new Error(`${label} contains an invalid checksum row: ${trimmed}`);\n    }\n    const name = match[2];\n    if (checksums.has(name)) {\n      throw new Error(`${label} contains duplicate checksum rows for ${name}`);\n    }\n    checksums.set(name, match[1].toLowerCase());\n  }\n  return checksums;\n}\n\nfunction assertExactNames(actualNames, expectedNames, label) {\n  const actual = new Set(actualNames);\n  const expected = new Set(expectedNames);\n  const missing = expectedNames.filter((name) => !actual.has(name));\n  const unexpected = actualNames.filter((name) => !expected.has(name));\n  if (missing.length > 0 || unexpected.length > 0 || actual.size !== actualNames.length) {\n    throw new Error(\n      `${label} does not match the authoritative inventory` +","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/scripts/release/assemble-release-assets.js#L22-L58","documentation":"Raised by parseChecksumManifest() in scripts/release/assemble-release-assets.js while reading CHECKSUM_MANIFEST or BUNDLE_CHECKSUM_MANIFEST: a non-empty line did not match the strict sha256sum row format ^([a-fA-F0-9]{64})\\s+\\*?(.+)$ — exactly 64 hex characters, whitespace, an optional binary-mode '*', then a filename. The offending line is reproduced verbatim in the message.","triggerScenarios":"A row carrying an md5/sha1 digest (32/40 hex chars); filename placed before the hash; no whitespace between hash and name; a stray header or comment line ('# sha256 sums'); a row truncated or wrapped by an editor; a line pasted from a different manifest format.","commonSituations":"Regenerating the manifest with a different tool (md5sum, sha1sum, or name-first column order); hand-editing the manifest after assembly; a truncated CI artifact download producing garbage lines; mixing another product's manifest into the asset directory.","solutions":["Regenerate the manifest in standard sha256sum form '<64-hex>  <name>' — the assemble step writes it itself, so avoid manual edits entirely","Delete or fix the exact line quoted in the message, then re-run node scripts/release/assemble-release-assets.js --verify ASSET_DIR","If the file arrived via CI download, re-download it: truncation and corruption show up as malformed rows"],"exampleFix":"# before (SHA1_SUMS.txt)\nd3f2ba81b4c05e9a...  codewhale-x86_64.tar.gz   # 40 hex chars -> invalid row\n\n# after (sha256sum format)\n9d86f4b1c0e2a7...64-hex-total...  codewhale-x86_64.tar.gz","handlingStrategy":"validation","validationCode":"const ROW = /^[a-fA-F0-9]{64}\\s+\\*?(.+)$/;\nfunction manifestRowsAreValid(content) {\n  return content\n    .split(/\\r?\\n/)\n    .filter((line) => line.trim() !== \"\")\n    .every((line) => ROW.test(line.trim()));\n}\n// run before invoking --verify:\nif (!manifestRowsAreValid(await fs.readFile(manifestPath, \"utf8\"))) {\n  throw new Error(`manifest at ${manifestPath} has malformed rows`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate manifests only with sha256sum's standard '<64-hex>  <name>' layout — never edit them by hand","Keep hashing pipeline consistent (always sha256, not md5/sha1) across build and release steps","Treat checksum-manifest edits in code review as a red flag: they should always be machine-written","After any artifact re-download, re-run --verify before upload"],"tags":["release","checksum","sha256","manifest","validation"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}