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

  1. Read the missing/unexpected lists in the message; delete unexpected files from the directory and regenerate or add missing ones.
  2. Regenerate the checksum manifest from the current asset set so both inventories match.
  3. 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

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


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)