{"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":"Error","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/3ee70a102609e550bd2e68004bf5990a9341c851/packages/shared/binary-installer/installer.mjs#L106-L142","documentation":"After the checksum manifest passes format validation, `expectedDigest` scans it for the exact artifact filename being installed. If no line's filename matches the requested artifact, the manifest is well-formed but does not describe this artifact, so the installer throws rather than install an unverified binary. This prevents installing a binary whose hash is simply absent from the signed manifest.","triggerScenarios":"`ensureBinary()` computing `expectedDigest(checksums, artifact)` where `artifact` (the platform-specific binary filename) is not listed in checksums.txt — e.g. installer version expects `caveman-mcp-linux-x64-v1.2.0` but the release only published `v1.1.0` artifacts, or a platform (musl/arm) that was never built for that release.","commonSituations":"Version skew: a newer installer/CLI asking for an artifact an older release doesn't ship; unsupported platform/arch combination not in the release matrix; artifact renamed in a release while local metadata still uses the old name.","solutions":["Check the artifact filename in the error against the files listed in the release's checksums.txt.","Pin/install a release version that actually publishes your platform's artifact.","If your platform genuinely isn't supported, install the binary manually (package manager or build from source) and export the envVar to point at it.","Clear stale caches (e.g. ~/.caveman) that may pin an outdated release URL, then retry."],"exampleFix":"// before: artifact missing from manifest\nawait ensureBinary({ name: \"caveman-mcp\", envVar: \"CAVEMAN_MCP_BIN\" });\n// after: supply a verified local binary\nexport CAVEMAN_MCP_BIN=/usr/local/bin/caveman-mcp","handlingStrategy":"fallback","validationCode":"const manifest = await fetch(`${release}/checksums.txt`).then(r => r.text());\nif (!manifest.includes(artifactName)) {\n  console.warn(`${artifactName} not in release manifest; provide binary via ${envVar}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await ensureBinary({ name, envVar });\n} catch (e) {\n  if (String(e.message).includes(\"does not contain\")) {\n    return installManuallyOrResolveFromPath(name, envVar);\n  }\n  throw e;\n}","preventionTips":["Confirm your platform/arch has a published artifact before relying on auto-install.","Keep installer and release versions in sync to avoid artifact-name skew.","Document a manual-install fallback for unsupported platforms.","Cache a known-good binary and point the envVar at it."],"tags":["supply-chain","checksum","not-found"],"backgroundTag":"resource-not-found","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"}