affaan-m/ECC · error

Harness capability catalog is out of sync with install…

Error message

Harness capability catalog is out of sync with install targets

What it means

validateCatalog throws this when the set of target ids catalogued in HARNESS_CAPABILITIES does not exactly equal both the SUPPORTED_INSTALL_TARGETS list and the ids registered by the install-target adapters (compared as sorted JSON). It is a three-way sync check between catalog, supported list, and adapters.

Solutions

  1. Update all three surfaces together: the adapter, SUPPORTED_INSTALL_TARGETS, and HARNESS_CAPABILITIES targetIds.
  2. Regenerate derived artifacts (`npm run catalog:sync`) and commit the diff.
  3. Run the catalog validation tests to see exactly which ids are missing or extra.
  4. If removing a target, delete it from all three lists and remove any adapterByTarget references.

Example fix

// before: adapter added, catalog not updated
SUPPORTED_INSTALL_TARGETS.add('windsurf-rules');
// HARNESS_CAPABILITIES lacks 'windsurf-rules'

// after
SUPPORTED_INSTALL_TARGETS.add('windsurf-rules');
HARNESS_CAPABILITIES.push({ id: 'windsurf', targetIds: ['windsurf-rules'], scopes: [{ targetId: 'windsurf-rules', root: '.windsurf' }] });
Defensive patterns

Strategy: validation

Validate before calling

const catalogued = HARNESS_CAPABILITIES.flatMap(h => h.targetIds).sort();
const supported = [...SUPPORTED_INSTALL_TARGETS].sort();
const registered = listInstallTargetAdapters().map(a => a.target).sort();
if (JSON.stringify(catalogued) !== JSON.stringify(supported) || JSON.stringify(catalogued) !== JSON.stringify(registered)) {
  throw new Error('Catalog, supported targets, and adapters are out of sync');
}

Try / catch

try {
  validateCatalog();
} catch (e) {
  if (/out of sync with install targets/.test(e.message)) {
    console.error('Update adapter list, SUPPORTED_INSTALL_TARGETS, and HARNESS_CAPABILITIES together.');
  }
  throw e;
}

Prevention

When it happens

Trigger: Adding/removing an install target adapter without updating HARNESS_CAPABILITIES; updating SUPPORTED_INSTALL_TARGETS but forgetting one of the other two lists; a merge where one side added a target to the catalog and the other to the adapters.

Common situations: Contributors wiring a new harness surface: they edit one file (e.g. add an adapter) but not the capability catalog; stale catalog after a target rename; CI sync test fails before any user-facing runtime impact.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at scripts/lib/harness-capabilities.js:288

}

function validateCatalog() {
  const adapters = listInstallTargetAdapters();
  const adapterByTarget = new Map(adapters.map(adapter => [adapter.target, adapter]));
  const catalogTargetIds = HARNESS_CAPABILITIES.flatMap(harness => harness.targetIds);

  if (new Set(catalogTargetIds).size !== catalogTargetIds.length) {
    throw new Error('Harness capability catalog contains duplicate install target ids');
  }

  const supported = [...SUPPORTED_INSTALL_TARGETS].sort();
  const registered = adapters.map(adapter => adapter.target).sort();
  const catalogued = [...catalogTargetIds].sort();
  if (
    JSON.stringify(catalogued) !== JSON.stringify(supported)
    || JSON.stringify(catalogued) !== JSON.stringify(registered)
  ) {
    throw new Error('Harness capability catalog is out of sync with install targets');
  }

  for (const harness of HARNESS_CAPABILITIES) {
    for (const declaredScope of harness.scopes) {
      const adapter = adapterByTarget.get(declaredScope.targetId);
      if (!adapter || expectedRootForAdapter(adapter) !== declaredScope.root) {
        throw new Error(
          `Harness capability root is out of sync for target ${declaredScope.targetId}`
        );
      }
    }
  }
}

validateCatalog();

function listHarnessCapabilities() {
  return HARNESS_CAPABILITIES.slice();

View on GitHub (pinned to 8321021c54)