{"record":{"id":"afe72c9f180cdf1d","repo":"affaan-m/ECC","slug":"metadata-filename-does-not-line-up-with-hookspath-n","errorCode":null,"errorMessage":"${METADATA_FILENAME} does not line up with ${hooksPath}:\\n  ${mismatches.join('\\n  ')}","messagePattern":"(.+?) does not line up with (.+?):\\\\n  (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/hooks-config.js","lineNumber":270,"sourceCode":"\n  for (const [event, eventMetadata] of Object.entries(entriesByEvent)) {\n    const entries = Array.isArray(events[event]) ? events[event] : [];\n    refreshed[event] = Array.isArray(eventMetadata)\n      ? eventMetadata.map((entry, index) => (\n        entry && typeof entry === 'object' && index < entries.length\n          ? { ...entry, fingerprint: fingerprintHookEntry(entries[index]) }\n          : entry\n      ))\n      : eventMetadata;\n  }\n\n  return { ...metadata, entries: refreshed };\n}\n\nfunction assertMetadataAligned(hooksConfig, metadata, hooksPath) {\n  const mismatches = findMetadataMismatches(hooksConfig, metadata);\n  if (mismatches.length > 0) {\n    throw new Error(\n      `${METADATA_FILENAME} does not line up with ${hooksPath}:\\n  ${mismatches.join('\\n  ')}`\n    );\n  }\n}\n\n/**\n * Merge a sidecar into a hooks config, rejecting a sidecar that does not line\n * up. Shared by the readers below so a truncated or reordered sidecar fails\n * loudly instead of producing entries with the wrong or missing ids.\n *\n * @param {object} hooksConfig - Parsed hooks.json.\n * @param {object} metadata - Parsed hooks.metadata.json.\n * @param {string} hooksPath - Used in the error message.\n * @returns {object} a new merged hooks configuration\n */\nfunction mergeHooksMetadata(hooksConfig, metadata, hooksPath = HOOKS_FILENAME) {\n  assertMetadataAligned(hooksConfig, metadata, hooksPath);\n  return applyHooksMetadata(hooksConfig, metadata);","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/hooks-config.js#L252-L288","documentation":"assertMetadataAligned() compares the hooks configuration against the metadata sidecar via findMetadataMismatches() and, if any mismatch is found, throws an error listing each mismatched location. It is the final gate in mergeHooksMetadata() ensuring the sidecar (METADATA_FILENAME) describes exactly the hooks present in hooksPath — same entries, same order/positions — before the merged result is accepted.","triggerScenarios":"Calling mergeHooksMetadata() (directly or through validateHooks flows) when hooks.json and the metadata sidecar disagree: entries added/removed in hooks.json only, fingerprints recomputed in one file but not the other, or a sidecar from a different project/branch copied over.","commonSituations":"Manually editing hooks.json without updating the sidecar; switching git branches where the two files diverged; restoring only one of the pair from backup; concurrent edits from two ECC sessions.","solutions":["Read the mismatch list in the error message — each line names the event/index that disagrees — and fix those spots in whichever file is stale.","Re-run the ECC merge/refresh tooling (which maintains the sidecar) instead of hand-editing hooks.json alone.","If one file is authoritative, regenerate the other: refresh sidecar fingerprints from hooks.json, or restore hooks.json from the sidecar's recorded state.","Ensure both files come from the same branch/commit (avoid mixed-checkout states)."],"exampleFix":"// before: hooks.json edited (new hook added) but .claude/hooks-metadata.json not updated\nassertMetadataAligned(cfg, metadata, hooksPath); // throws with mismatch list\n// after: update sidecar to include the new entry's fingerprint at matching position\nmetadata.entries.Stop.splice(0, 0, fingerprintOf(newHook));\nassertMetadataAligned(cfg, metadata, hooksPath); // passes","handlingStrategy":"try-catch","validationCode":"const mismatches = findMetadataMismatches(hooksConfig, metadata);\nif (mismatches.length > 0) {\n  console.error('Sidecar out of sync; run the ECC merge tooling or restore the matching sidecar before merging.');\n  process.exit(1);\n}\nmergeHooksMetadata(/* ... */);","typeGuard":"function isMetadataInSync(hooksConfig, metadata) {\n  return findMetadataMismatches(hooksConfig, metadata).length === 0;\n}","tryCatchPattern":"try {\n  mergeHooksMetadata(/* ... */);\n} catch (err) {\n  if (String(err.message).includes('does not line up with')) {\n    console.error(err.message); // prints the per-location mismatch list\n    console.error('Fix each listed location in the stale file, or restore both files from the same commit.');\n  } else throw err;\n}","preventionTips":["Always edit hooks via mergeHooksMetadata/addJsonMergeOperation so the sidecar updates together.","Commit hooks.json and its metadata sidecar in the same commit; never restore one without the other.","After branch switches, verify both files come from the same tree before running hooks tooling.","Read the mismatch list in the error — it pinpoints exactly which entries to fix."],"tags":["hooks","metadata","consistency","sidecar"],"backgroundTag":"checksum-mismatch","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}