{"record":{"id":"5f235d214d5cd6a6","repo":"affaan-m/ECC","slug":"harness-capability-catalog-is-out-of-sync-with-ins","errorCode":null,"errorMessage":"Harness capability catalog is out of sync with install targets","messagePattern":"Harness capability catalog is out of sync with install targets","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/harness-capabilities.js","lineNumber":274,"sourceCode":"}\n\nfunction validateCatalog() {\n  const adapters = listInstallTargetAdapters();\n  const adapterByTarget = new Map(adapters.map(adapter => [adapter.target, adapter]));\n  const catalogTargetIds = HARNESS_CAPABILITIES.flatMap(harness => harness.targetIds);\n\n  if (new Set(catalogTargetIds).size !== catalogTargetIds.length) {\n    throw new Error('Harness capability catalog contains duplicate install target ids');\n  }\n\n  const supported = [...SUPPORTED_INSTALL_TARGETS].sort();\n  const registered = adapters.map(adapter => adapter.target).sort();\n  const catalogued = [...catalogTargetIds].sort();\n  if (\n    JSON.stringify(catalogued) !== JSON.stringify(supported)\n    || JSON.stringify(catalogued) !== JSON.stringify(registered)\n  ) {\n    throw new Error('Harness capability catalog is out of sync with install targets');\n  }\n\n  for (const harness of HARNESS_CAPABILITIES) {\n    for (const declaredScope of harness.scopes) {\n      const adapter = adapterByTarget.get(declaredScope.targetId);\n      if (!adapter || expectedRootForAdapter(adapter) !== declaredScope.root) {\n        throw new Error(\n          `Harness capability root is out of sync for target ${declaredScope.targetId}`\n        );\n      }\n    }\n  }\n}\n\nvalidateCatalog();\n\nfunction listHarnessCapabilities() {\n  return HARNESS_CAPABILITIES.slice();","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/affaan-m/ECC/blob/d8409a4b0813771235555e32e3d8046a73988bfa/scripts/lib/harness-capabilities.js#L256-L292","documentation":"The second require-time catalog validation: the sorted set of all catalogued target ids must deep-equal both SUPPORTED_INSTALL_TARGETS (the supported list in install-manifests.js) and the registered install-target adapters. Any target that is supported/registered but missing from the catalog — or catalogued but not registered — throws at module load, keeping the three sources of truth locked together.","triggerScenarios":"Adding a new install target: the adapter file is created and SUPPORTED_INSTALL_TARGETS updated, but no harness entry lists the new targetId. Or the reverse: a targetId is catalogued while its adapter isn't registered (e.g. the adapter module isn't imported by listInstallTargetAdapters).","commonSituations":"Onboarding a new harness in two PRs where the adapter lands first; renaming a target id in one place only; deleting an adapter without pruning the catalog; merge conflicts resolved by keeping the adapter but dropping the catalog line.","solutions":["Diff the three lists: SUPPORTED_INSTALL_TARGETS, adapters.map(a => a.target), and the union of harness.targetIds — the message fires when sorted unions differ","Update all three in the same commit: register the adapter, add the id to SUPPORTED_INSTALL_TARGETS, and list it in exactly one harness's targetIds","Verify with `node -e \"require('./scripts/lib/harness-capabilities.js')\"`","Run the repo's install-surface tests (npm test) which exercise catalog/adapter consistency"],"exampleFix":"// before: adapter 'zed' registered + supported, but no harness lists it\n// after\n{ id: 'editors', targetIds: ['zed', 'cursor'] },","handlingStrategy":"validation","validationCode":"// CI guard: catalog, supported list, and adapters must match exactly\nconst { HARNESS_CAPABILITIES } = require('./scripts/lib/harness-capabilities.js');\nconst { SUPPORTED_INSTALL_TARGETS } = require('./scripts/lib/install-manifests.js');\nconst catalogued = [...new Set(HARNESS_CAPABILITIES.flatMap(h => h.targetIds))].sort();\nconst supported = [...SUPPORTED_INSTALL_TARGETS].sort();\nif (JSON.stringify(catalogued) !== JSON.stringify(supported)) {\n  throw new Error(`Drift: catalog=${catalogued} vs supported=${supported}`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Change adapter registration, SUPPORTED_INSTALL_TARGETS, and catalog targetIds together in one commit","Keep the require-smoke-test in CI so drift fails the build, not users","During harness onboarding, use the existing entry as a checklist of every place a target id must appear"],"tags":["internal-invariant","catalog","sync","module-load","developer-error"],"backgroundTag":"catalog-out-of-sync","analyzedSha":"d8409a4b0813771235555e32e3d8046a73988bfa","analyzedAt":"2026-08-26T12:15:34.022Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}