{"record":{"id":"fb0c3af2c953a2ff","repo":"JuliusBrussee/caveman","slug":"signed-checksum-manifest-does-not-contain-artifa","errorCode":null,"errorMessage":"signed checksum manifest does not contain ${artifact}","messagePattern":"signed checksum manifest does not contain (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/shared/binary-installer/installer.mjs","lineNumber":124,"sourceCode":"    return verify(\n      \"sha256\",\n      Buffer.from(checksums),\n      createPublicKey(BINARY_SIGNING_PUBKEY),\n      Buffer.from(bundle.messageSignature.signature, \"base64\"),\n    );\n  } catch {\n    return false;\n  }\n}\n\nfunction expectedDigest(checksums, artifact) {\n  for (const line of checksums.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(\"signed checksum manifest is malformed\");\n    if (match[2] === artifact) return match[1];\n  }\n  throw new Error(`signed checksum manifest does not contain ${artifact}`);\n}\n\nfunction cleanup(path) {\n  try {\n    unlinkSync(path);\n  } catch (error) {\n    if (error.code !== \"ENOENT\") throw error;\n  }\n}\n\nasync function download(url, part, timeout) {\n  const response = await asset(url, timeout);\n  if (!response.body) throw new Error(\"binary download failed: response body missing\");\n  const hash = createHash(\"sha256\");\n  const file = await open(part, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY, 0o600);\n  const reader = response.body.getReader();\n  try {\n    while (true) {","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/shared/binary-installer/installer.mjs#L106-L142","documentation":"expectedDigest() scanned every well-formed line of the signature-verified checksums.txt and none matched the requested artifact name ('<name>_<os>_<arch>', for example caveman-mcp_linux_arm64). The manifest is valid but incomplete for this platform — there is nothing safe to verify the download against, so the install stops.","triggerScenarios":"A release published with artifacts for only some platforms (for example linux/amd64 and darwin/arm64 present, linux/arm64 absent) while running on the missing one; a name mismatch between the locally computed artifact string and the release pipeline's file naming.","commonSituations":"Partial release uploads; custom mirrors syncing only the platforms the mirror owner uses; release scripts with per-platform build failures that still publish checksums for the succeeded subset.","solutions":["Check the release's checksums.txt for your platform's artifact name to confirm the gap, then run on a platform the release covers","Install the binary for your platform by another route and point the env var at it (CAVEMAN_MCP_BIN / CAVEMAN_SHRINK_BIN / CAVEMAN_BROWSE_BIN)","Report the missing artifact upstream so the release publishes all six supported pairs"],"exampleFix":"# before: release lacks caveman-mcp_linux_arm64\n#   signed checksum manifest does not contain caveman-mcp_linux_arm64\n\n# after: self-supply the binary\nexport CAVEMAN_MCP_BIN=/opt/caveman/bin/caveman-mcp   # built or downloaded for arm64","handlingStrategy":"validation","validationCode":"// before setup: confirm this release ships your platform's artifact\nconst txt = await (await fetch(`${release}/checksums.txt`)).text();\nif (!txt.split(\"\\n\").some((l) => l.endsWith(` ${name}_${process.platform}_${arch}`))) {\n  process.env[envVar] = \"/path/to/self-supplied-binary\"; // avoid the missing-artifact install path\n}","typeGuard":"function manifestCovers(manifest, artifact) {\n  return manifest.split(\"\\n\").some((l) => l.endsWith(`  ${artifact}`));\n}","tryCatchPattern":"try { await ensureBinary({ name, envVar }); }\ncatch (e) {\n  if (/does not contain/.test(String(e?.message)) && process.env[envVar]) return process.env[envVar];\n  throw e;\n}","preventionTips":["Check the release's checksums.txt for your os/arch before automating installs on new platforms","Keep a self-built binary and its CAVEMAN_*_BIN override for platforms absent from the release"],"tags":["installer","checksum","platform"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}