affaan-m/ECC · error
Harness capability root is out of sync for target
Error message
Harness capability root is out of sync for target ${declaredScope.targetId} What it means
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.
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.
Example fix
// before
{ targetId: 'skills', root: 'skills' } // adapter now derives '.agents/skills'
// after
{ targetId: 'skills', root: '.agents/skills' } Defensive patterns
Strategy: validation
Validate before calling
for (const harness of HARNESS_CAPABILITIES) {
for (const scope of harness.scopes) {
const adapter = adapterByTarget.get(scope.targetId);
if (!adapter || expectedRootForAdapter(adapter) !== scope.root) {
throw new Error(`Scope root mismatch for ${scope.targetId}: declared ${scope.root}`);
}
}
} Try / catch
try {
validateCatalog();
} catch (e) {
const m = /root is out of sync for target (\S+)/.exec(e.message);
if (m) console.error(`Fix scope root or targetId for: ${m[1]}`);
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
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
- Harness capability catalog is out of sync with install…
- Harness capability catalog contains duplicate install…
- no style pack ' ' under - run mint.py first
- agent profile inheritance cycle
- An install config path is required
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/56194bb2cc3c0a14.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/harness-capabilities.js:295
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();
}
function listGuidedHarnesses() {
return GUIDED_HARNESS_IDS.map(id => LOOKUP.get(id));
}
function getHarnessCapability(value) {View on GitHub (pinned to 8321021c54)