{"record":{"id":"2c822dbad8e66d72","repo":"JuliusBrussee/caveman","slug":"invalid-checksum-manifest-line-json-stringify-line","errorCode":null,"errorMessage":"invalid checksum manifest line: ${JSON.stringify(line)}","messagePattern":"invalid checksum manifest line: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":2277,"sourceCode":"function verifiedLocalInstall(binDir: string): InstalledBinary[] | null {\n  const manifest = readBinaryInstallManifest();\n  if (!manifest || manifest.release !== BINARY_RELEASE) return null;\n  const installed: InstalledBinary[] = [];\n  for (const name of INSTALL_BINARIES) {\n    const expected = manifest.artifacts[name];\n    const path = join(binDir, binaryInstallFilename(name));\n    if (!expected || sha256File(path) !== expected) return null;\n    installed.push({ name, path, sha256: expected, status: \"already installed\" });\n  }\n  return installed;\n}\n\nfunction parseSignedChecksums(raw: string): Map<string, string> {\n  const checksums = new Map<string, string>();\n  for (const line of raw.split(\"\\n\")) {\n    if (!line) continue;\n    const match = line.match(/^([a-f0-9]{64})  ([A-Za-z0-9._-]+)$/);\n    if (!match) throw new Error(`invalid checksum manifest line: ${JSON.stringify(line)}`);\n    const filename = match[2]!;\n    if (checksums.has(filename)) throw new Error(`duplicate checksum manifest entry: ${filename}`);\n    checksums.set(filename, match[1]!);\n  }\n  return checksums;\n}\n\nfunction verifyChecksumSignature(checksums: string, signature: string): boolean {\n  try {\n    const bundle = JSON.parse(signature) as {\n      mediaType?: unknown;\n      messageSignature?: {\n        messageDigest?: { algorithm?: unknown; digest?: unknown };\n        signature?: unknown;\n      };\n    };\n    if (bundle.mediaType !== \"application/vnd.dev.sigstore.bundle.v0.3+json\") return false;\n    if (bundle.messageSignature?.messageDigest?.algorithm !== \"SHA2_256\") return false;","sourceCodeStart":2259,"sourceCodeEnd":2295,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/cli/src/index.ts#L2259-L2295","documentation":"parseSignedChecksums parses a sha256sum-style manifest line-by-line, requiring each non-empty line to match exactly '<64 hex chars>  <filename>' (two spaces). Any deviating line throws with the offending line JSON-escaped.","triggerScenarios":"Downloading/supplying a checksum manifest with a truncated hash, a single space instead of two, BSD-style 'SHA256 (...)' format, CRLF line endings (the \\r makes the filename regex fail), or extra commentary lines.","commonSituations":"Hand-editing the manifest and breaking the two-space separator; generating the manifest with `shasum -a 256` plus annotations; transferring the file through a tool that added CRLF endings.","solutions":["Regenerate the manifest with sha256sum so lines match '<hash>  <name>' with two spaces.","Normalize line endings: dos2unix checksums.txt.","Remove any comment/header lines and verify each hash is exactly 64 lowercase hex characters."],"exampleFix":"// before\nSHA256 (cave-linux-amd64) = abc123...\n\n// after\n$ sha256sum cave-linux-amd64 > checksums.txt\nabc123...<64 hex>  cave-linux-amd64","handlingStrategy":"validation","validationCode":"const lineRe = /^[a-f0-9]{64}  [A-Za-z0-9._-]+$/;\nfor (const line of raw.split('\\n')) {\n  if (line && !lineRe.test(line)) throw new Error(`malformed manifest line (need '<64-hex>  <name>', LF endings): ${line}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  verify(manifest);\n} catch (error) {\n  if (error.message.startsWith('invalid checksum manifest line')) {\n    console.error(`${error.message}\\nRegenerate with: sha256sum <files> > checksums.txt`);\n  } else throw error;\n}","preventionTips":["Generate manifests only with sha256sum, never hand-edited","Run dos2unix on manifests that crossed Windows systems (CRLF breaks the regex)","Don't append headers/comments to the manifest file"],"tags":["checksums","parsing","validation"],"backgroundTag":"invalid-argument-format","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}