affaan-m/ECC · error

does not line up with :\n

Error message

${METADATA_FILENAME} does not line up with ${hooksPath}:\n  ${mismatches.join('\n  ')}

What it means

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.

Solutions

  1. 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.
  2. Re-run the ECC merge/refresh tooling (which maintains the sidecar) instead of hand-editing hooks.json alone.
  3. If one file is authoritative, regenerate the other: refresh sidecar fingerprints from hooks.json, or restore hooks.json from the sidecar's recorded state.
  4. Ensure both files come from the same branch/commit (avoid mixed-checkout states).

Example fix

// before: hooks.json edited (new hook added) but .claude/hooks-metadata.json not updated
assertMetadataAligned(cfg, metadata, hooksPath); // throws with mismatch list
// after: update sidecar to include the new entry's fingerprint at matching position
metadata.entries.Stop.splice(0, 0, fingerprintOf(newHook));
assertMetadataAligned(cfg, metadata, hooksPath); // passes
Defensive patterns

Strategy: try-catch

Validate before calling

const mismatches = findMetadataMismatches(hooksConfig, metadata);
if (mismatches.length > 0) {
  console.error('Sidecar out of sync; run the ECC merge tooling or restore the matching sidecar before merging.');
  process.exit(1);
}
mergeHooksMetadata(/* ... */);

Type guard

function isMetadataInSync(hooksConfig, metadata) {
  return findMetadataMismatches(hooksConfig, metadata).length === 0;
}

Try / catch

try {
  mergeHooksMetadata(/* ... */);
} catch (err) {
  if (String(err.message).includes('does not line up with')) {
    console.error(err.message); // prints the per-location mismatch list
    console.error('Fix each listed location in the stale file, or restore both files from the same commit.');
  } else throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/afe72c9f180cdf1d. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/hooks-config.js:270

  for (const [event, eventMetadata] of Object.entries(entriesByEvent)) {
    const entries = Array.isArray(events[event]) ? events[event] : [];
    refreshed[event] = Array.isArray(eventMetadata)
      ? eventMetadata.map((entry, index) => (
        entry && typeof entry === 'object' && index < entries.length
          ? { ...entry, fingerprint: fingerprintHookEntry(entries[index]) }
          : entry
      ))
      : eventMetadata;
  }

  return { ...metadata, entries: refreshed };
}

function assertMetadataAligned(hooksConfig, metadata, hooksPath) {
  const mismatches = findMetadataMismatches(hooksConfig, metadata);
  if (mismatches.length > 0) {
    throw new Error(
      `${METADATA_FILENAME} does not line up with ${hooksPath}:\n  ${mismatches.join('\n  ')}`
    );
  }
}

/**
 * Merge a sidecar into a hooks config, rejecting a sidecar that does not line
 * up. Shared by the readers below so a truncated or reordered sidecar fails
 * loudly instead of producing entries with the wrong or missing ids.
 *
 * @param {object} hooksConfig - Parsed hooks.json.
 * @param {object} metadata - Parsed hooks.metadata.json.
 * @param {string} hooksPath - Used in the error message.
 * @returns {object} a new merged hooks configuration
 */
function mergeHooksMetadata(hooksConfig, metadata, hooksPath = HOOKS_FILENAME) {
  assertMetadataAligned(hooksConfig, metadata, hooksPath);
  return applyHooksMetadata(hooksConfig, metadata);

View on GitHub (pinned to 8321021c54)