Hmbown/CodeWhale · error · Error
${label} contains duplicate checksum rows for ${name}
Error message
${label} contains duplicate checksum rows for ${name} What it means
parseChecksumManifest() found two rows for the same filename in a checksum manifest and refuses the ambiguous input. The Map-based parse keeps one digest per basename, so a duplicate row means the manifest was concatenated, double-generated, or edited and cannot attest a single hash per asset. The conflicting basename is named in the message.
Source
Thrown at scripts/release/assemble-release-assets.js:44
const hash = crypto.createHash("sha256");
hash.update(await fs.readFile(filePath));
return hash.digest("hex");
}
function parseChecksumManifest(content, label) {
const checksums = new Map();
for (const line of content.split(/\r?\n/)) {
const trimmed = line.trim();
if (!trimmed) {
continue;
}
const match = trimmed.match(/^([a-fA-F0-9]{64})\s+\*?(.+)$/);
if (!match) {
throw new Error(`${label} contains an invalid checksum row: ${trimmed}`);
}
const name = match[2];
if (checksums.has(name)) {
throw new Error(`${label} contains duplicate checksum rows for ${name}`);
}
checksums.set(name, match[1].toLowerCase());
}
return checksums;
}
function assertExactNames(actualNames, expectedNames, label) {
const actual = new Set(actualNames);
const expected = new Set(expectedNames);
const missing = expectedNames.filter((name) => !actual.has(name));
const unexpected = actualNames.filter((name) => !expected.has(name));
if (missing.length > 0 || unexpected.length > 0 || actual.size !== actualNames.length) {
throw new Error(
`${label} does not match the authoritative inventory` +
`${missing.length > 0 ? `; missing: ${missing.join(", ")}` : ""}` +
`${unexpected.length > 0 ? `; unexpected: ${unexpected.join(", ")}` : ""}` +
`${actual.size !== actualNames.length ? "; duplicate basenames are present" : ""}`,
);View on GitHub (pinned to 8880682c63)
Solutions
- Remove the duplicate row so each basename appears exactly once, keeping the row whose hash matches the actual file (verify with sha256sum)
- Prefer regenerating the manifest via the assemble script instead of editing it
- If two artifacts legitimately share a basename, rename one — the release inventory requires unique basenames (assertExactNames also rejects duplicates)
Example fix
# before 9d86... codewhale-x86_64.tar.gz 4e97... codewhale-x86_64.tar.gz # duplicate row # after 9d86... codewhale-x86_64.tar.gz
Defensive patterns
Strategy: validation
Validate before calling
function findDuplicateManifestRows(content) {
const seen = new Set();
const duplicates = [];
for (const line of content.split(/\r?\n/)) {
const match = line.trim().match(/^[a-fA-F0-9]{64}\s+\*?(.+)$/);
if (!match) continue;
if (seen.has(match[2])) duplicates.push(match[2]);
seen.add(match[2]);
}
return duplicates;
} Prevention
- Never concatenate manifests from parallel jobs — merge with dedupe by basename or generate one manifest at the end
- When regenerating, overwrite the manifest file rather than appending
- Enforce unique artifact basenames in the build config so duplicates cannot arise downstream
When it happens
Trigger: Concatenating two manifest files covering overlapping assets; a generator appending instead of overwriting; copy-paste duplication while hand-editing; the same bundle listed under both plain and *-prefixed forms that normalize to the same name.
Common situations: Merging manifests from parallel CI jobs without dedupe; a buggy custom packaging script appending rows on retry; manual re-addition of a 'missing' row that was actually present.
Related errors
- ${label} contains an invalid checksum row: ${trimmed}
- Thread summaries require the runtime bearer token.
- Restore points require the runtime bearer token.
- Restore points returned HTTP ${response.statusCode}.
- ${label} does not match the authoritative inventory; missing
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/bda040e3ce3914d8.
Report an issue: GitHub.