{"record":{"id":"95473d19d3eeb0e1","repo":"Hmbown/CodeWhale","slug":"label-does-not-match-the-authoritative-inventory-missing","errorCode":null,"errorMessage":"${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\" : \"\"}","messagePattern":"(.+?) does not match the authoritative inventory(.+?)` : \"\"\\}(.+?)` : \"\"\\}(.+?)","errorType":"console","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/release/assemble-release-assets.js","lineNumber":57,"sourceCode":"    if (!match) {\n      throw new Error(`${label} contains an invalid checksum row: ${trimmed}`);\n    }\n    const name = match[2];\n    if (checksums.has(name)) {\n      throw new Error(`${label} contains duplicate checksum rows for ${name}`);\n    }\n    checksums.set(name, match[1].toLowerCase());\n  }\n  return checksums;\n}\n\nfunction assertExactNames(actualNames, expectedNames, label) {\n  const actual = new Set(actualNames);\n  const expected = new Set(expectedNames);\n  const missing = expectedNames.filter((name) => !actual.has(name));\n  const unexpected = actualNames.filter((name) => !expected.has(name));\n  if (missing.length > 0 || unexpected.length > 0 || actual.size !== actualNames.length) {\n    throw new Error(\n      `${label} does not match the authoritative inventory` +\n        `${missing.length > 0 ? `; missing: ${missing.join(\", \")}` : \"\"}` +\n        `${unexpected.length > 0 ? `; unexpected: ${unexpected.join(\", \")}` : \"\"}` +\n        `${actual.size !== actualNames.length ? \"; duplicate basenames are present\" : \"\"}`,\n    );\n  }\n}\n\nasync function assertManifest(directory, manifestName, expectedNames) {\n  const manifestPath = path.join(directory, manifestName);\n  const checksums = parseChecksumManifest(\n    await fs.readFile(manifestPath, \"utf8\"),\n    manifestName,\n  );\n  assertExactNames([...checksums.keys()], expectedNames, manifestName);\n  for (const name of expectedNames) {\n    const actual = await sha256(path.join(directory, name));\n    if (checksums.get(name) !== actual) {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/scripts/release/assemble-release-assets.js#L39-L75","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n# directory has app-linux.zip from an old build; manifest lacks it\n// after\nrm assets/app-linux.zip  # or rebuild it, then regenerate SHA256SUMS","handlingStrategy":"validation","validationCode":"const expected = allReleaseAssetNames();\nconst actual = (await fs.readdir(assetDir)).sort();\nconst exp = [...new Set(expected)].sort();\nconsole.log('missing:', exp.filter(n => !actual.includes(n)), 'unexpected:', actual.filter(n => !exp.includes(n)));","typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["Start each release from a clean asset directory.","Regenerate the manifest whenever the asset list changes.","Diff directory contents against allReleaseAssetNames() before assembling."],"tags":["release","inventory-mismatch","checksums"],"backgroundTag":"schema-validation-failed","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}