{"record":{"id":"56194bb2cc3c0a14","repo":"affaan-m/ECC","slug":"harness-capability-root-is-out-of-sync-for-target","errorCode":null,"errorMessage":"Harness capability root is out of sync for target ${declaredScope.targetId}","messagePattern":"Harness capability root is out of sync for target (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/harness-capabilities.js","lineNumber":295,"sourceCode":"  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();\n}\n\nfunction listGuidedHarnesses() {\n  return GUIDED_HARNESS_IDS.map(id => LOOKUP.get(id));\n}\n\nfunction getHarnessCapability(value) {","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/harness-capabilities.js#L277-L313","documentation":"validateCatalog checks each harness-declared scope against the corresponding install-target adapter: the adapter must exist and expectedRootForAdapter(adapter) must equal the scope's declared root. Any mismatch throws this message naming the offending targetId. It guarantees declared scope roots stay in sync with adapter-derived filesystem roots.","triggerScenarios":"Changing an adapter's root path logic (expectedRootForAdapter) without updating the hardcoded root in HARNESS_CAPABILITIES scopes; a typo in a scope's targetId so adapterByTarget.get returns undefined; adding a scope entry with a stale root after a directory-layout change.","commonSituations":"Refactoring install directories (e.g. moving skills from skills/ to .agents/skills/) and updating the adapter but not the catalog; renaming a target id in adapters only; a new harness scope entry copied from another harness with the wrong root.","solutions":["Fix the targetId typo or point the scope at an existing adapter id.","Update the scope's declared root in HARNESS_CAPABILITIES to match expectedRootForAdapter(adapter).","Run the catalog tests after any change to adapter root logic to re-derive expected roots.","If the layout changed intentionally, update both the adapter and every scope declaration referencing it."],"exampleFix":"// before\n{ targetId: 'skills', root: 'skills' } // adapter now derives '.agents/skills'\n\n// after\n{ targetId: 'skills', root: '.agents/skills' }","handlingStrategy":"validation","validationCode":"for (const harness of HARNESS_CAPABILITIES) {\n  for (const scope of harness.scopes) {\n    const adapter = adapterByTarget.get(scope.targetId);\n    if (!adapter || expectedRootForAdapter(adapter) !== scope.root) {\n      throw new Error(`Scope root mismatch for ${scope.targetId}: declared ${scope.root}`);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  validateCatalog();\n} catch (e) {\n  const m = /root is out of sync for target (\\S+)/.exec(e.message);\n  if (m) console.error(`Fix scope root or targetId for: ${m[1]}`);\n  throw e;\n}","preventionTips":["When changing adapter root logic, derive scope roots from the adapter instead of hardcoding.","Run catalog tests after any directory-layout refactor.","Copy scope entries carefully — verify targetId and root when duplicating between harnesses."],"tags":["config","sync","catalog","path"],"backgroundTag":"internal-invariant-violation","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"}