Hmbown/CodeWhale · error · Error
does not match the authoritative inventory ` : ""} ` : ""}
Error message
${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" : ""} What it means
assertExactNames compares an actual set of names against the authoritative expected inventory and throws when they differ in any way: expected names are missing, unexpected extra names exist, or the actual list contains duplicate basenames. The message appends which of the three problems applies and lists the offenders.
Solutions
- Read the missing/unexpected lists in the message; delete unexpected files from the directory and regenerate or add missing ones.
- Regenerate the checksum manifest from the current asset set so both inventories match.
- Clean the asset/output directory before assembling to remove stale artifacts from prior builds.
Example fix
// before # directory has app-linux.zip from an old build; manifest lacks it // after rm assets/app-linux.zip # or rebuild it, then regenerate SHA256SUMS
Defensive patterns
Strategy: validation
Validate before calling
const expected = allReleaseAssetNames();
const actual = (await fs.readdir(assetDir)).sort();
const exp = [...new Set(expected)].sort();
console.log('missing:', exp.filter(n => !actual.includes(n)), 'unexpected:', actual.filter(n => !exp.includes(n))); Try / catch
try { await verifyAssetDirectory(dir); } catch (e) { if (String(e.message).includes('authoritative inventory')) { console.error('Clean the asset dir / regenerate the manifest:', e.message); process.exitCode = 1; } else throw e; } Prevention
- Start each release from a clean asset directory.
- Regenerate the manifest whenever the asset list changes.
- Diff directory contents against allReleaseAssetNames() before assembling.
When it happens
Trigger: verifyAssetDirectory finding files in the release directory not produced by allReleaseAssetNames(), assertManifest seeing checksum rows for assets that were not built (or vice versa), or a directory listing containing the same basename twice.
Common situations: Stale artifacts left over from a previous release in the asset directory, a renamed/removed asset not reflected in the manifest, or a manifest generated before the asset list changed.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- contains an invalid checksum row
- contains duplicate checksum rows for
- checksum mismatch for
- Annotated tag did not peel to a commit SHA
- build platform HTTP client
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/95473d19d3eeb0e1.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/release/assemble-release-assets.js:57
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" : ""}`,
);
}
}
async function assertManifest(directory, manifestName, expectedNames) {
const manifestPath = path.join(directory, manifestName);
const checksums = parseChecksumManifest(
await fs.readFile(manifestPath, "utf8"),
manifestName,
);
assertExactNames([...checksums.keys()], expectedNames, manifestName);
for (const name of expectedNames) {
const actual = await sha256(path.join(directory, name));
if (checksums.get(name) !== actual) {View on GitHub (pinned to 433685b202)