JuliusBrussee/caveman · error
duplicate checksum manifest entry
Error message
duplicate checksum manifest entry: ${filename} What it means
parseSignedChecksums builds a Map keyed by filename and throws if the same filename appears twice in the manifest. Duplicate entries make the signature verification ambiguous, so the whole manifest is rejected.
Solutions
- Regenerate the manifest in one pass (sha256sum * > checksums.txt) instead of appending.
- Deduplicate with `awk '!seen[$2]++' checksums.txt` after confirming entries agree.
- Diff the two merged manifests and keep only the current release's entries.
Example fix
// before (appended twice) abc... cave-darwin-arm64 def... cave-darwin-arm64 // after abc... cave-darwin-arm64
Defensive patterns
Strategy: validation
Validate before calling
const names = raw.split('\n').filter(Boolean).map(l => l.match(/^[a-f0-9]{64} ([A-Za-z0-9._-]+)$/)?.[1]);
const dupes = names.filter((n, i) => n && names.indexOf(n) !== i);
if (dupes.length) throw new Error(`duplicate manifest entries: ${[...new Set(dupes)].join(', ')}`); Try / catch
try {
verify(manifest);
} catch (error) {
if (error.message.startsWith('duplicate checksum manifest entry')) {
console.error(`${error.message}\nRegenerate the manifest in a single pass instead of appending.`);
} else throw error;
} Prevention
- Write manifests with `>` (overwrite), never `>>` (append)
- Deduplicate with `awk '!seen[$2]++'` when merging manifests
- Regenerate the whole manifest after adding or updating binaries
When it happens
Trigger: A checksum manifest generated by concatenating two manifest files (or running sha256sum twice with append), producing the same filename on two lines.
Common situations: CI scripts doing `sha256sum * >> checksums.txt` on retries; merging an updated manifest into an old one without deduplication.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- invalid checksum manifest line
- not valid JSON
- apiKey, baseURL, and agent are required
- arm must be or
- artifact_id is required
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/c74d41082f708ae3.
Report an issue: GitHub.
Appendix: source
Thrown at packages/cli/src/index.ts:2279
if (!manifest || manifest.release !== BINARY_RELEASE) return null;
const installed: InstalledBinary[] = [];
for (const name of INSTALL_BINARIES) {
const expected = manifest.artifacts[name];
const path = join(binDir, binaryInstallFilename(name));
if (!expected || sha256File(path) !== expected) return null;
installed.push({ name, path, sha256: expected, status: "already installed" });
}
return installed;
}
function parseSignedChecksums(raw: string): Map<string, string> {
const checksums = new Map<string, string>();
for (const line of raw.split("\n")) {
if (!line) continue;
const match = line.match(/^([a-f0-9]{64}) ([A-Za-z0-9._-]+)$/);
if (!match) throw new Error(`invalid checksum manifest line: ${JSON.stringify(line)}`);
const filename = match[2]!;
if (checksums.has(filename)) throw new Error(`duplicate checksum manifest entry: ${filename}`);
checksums.set(filename, match[1]!);
}
return checksums;
}
function verifyChecksumSignature(checksums: string, signature: string): boolean {
try {
const bundle = JSON.parse(signature) as {
mediaType?: unknown;
messageSignature?: {
messageDigest?: { algorithm?: unknown; digest?: unknown };
signature?: unknown;
};
};
if (bundle.mediaType !== "application/vnd.dev.sigstore.bundle.v0.3+json") return false;
if (bundle.messageSignature?.messageDigest?.algorithm !== "SHA2_256") return false;
if (typeof bundle.messageSignature.messageDigest.digest !== "string") return false;
if (typeof bundle.messageSignature.signature !== "string") return false;View on GitHub (pinned to 3ee70a1026)