affaan-m/ECC · error
Harness capability catalog contains duplicate install…
Error message
Harness capability catalog contains duplicate install target ids
What it means
validateCatalog enforces that every install-target id across HARNESS_CAPABILITIES is unique; it throws when new Set(catalogTargetIds).size !== catalogTargetIds.length. This is a startup consistency invariant ensuring each target id maps to exactly one capability entry.
Solutions
- Search HARNESS_CAPABILITIES for the duplicated targetId and remove it from the wrong harness.
- If two harnesses legitimately share an install surface, factor it into one harness entry instead of duplicating the id.
- Run the catalog tests (`npm test`) after edits to catch duplicates immediately.
- Regenerate any derived catalogs (`npm run catalog:sync`) after fixing.
Example fix
// before
const HARNESS_CAPABILITIES = [
{ id: 'codex', targetIds: ['agents'] },
{ id: 'cursor', targetIds: ['agents'] }, // duplicate
];
// after
const HARNESS_CAPABILITIES = [
{ id: 'codex', targetIds: ['agents'] },
{ id: 'cursor', targetIds: ['cursor-rules'] },
]; Defensive patterns
Strategy: validation
Validate before calling
const ids = HARNESS_CAPABILITIES.flatMap(h => h.targetIds);
if (new Set(ids).size !== ids.length) {
const dupes = ids.filter((id, i) => ids.indexOf(id) !== i);
throw new Error(`Duplicate target ids: ${[...new Set(dupes)].join(', ')}`);
} Try / catch
try {
validateCatalog();
} catch (e) {
if (/duplicate install target ids/.test(e.message)) {
console.error('Catalog edit introduced a duplicate targetId — remove it before shipping.');
}
throw e;
} Prevention
- Run the catalog tests locally before every PR touching harness-capabilities.js.
- Grep for the new targetId across HARNESS_CAPABILITIES before adding it.
- Remove old targetIds when renaming instead of keeping both.
When it happens
Trigger: Editing HARNESS_CAPABILITIES and listing the same targetId under two harnesses (copy-paste when adding a new harness or target); merging branches that both added the same target id.
Common situations: Contributors adding a new harness entry in scripts/lib/harness-capabilities.js and accidentally duplicating an existing targetIds entry; a rename left the old id in place alongside the new one; the project's own test suite catches it first.
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…
- Claude settings contains multiple hooks for event
- genre numbers must be distinct
- Harness capability root is out of sync for target
- agent profile inheritance cycle
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/93a38b81af1a93f2.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/harness-capabilities.js:278
}
}
function expectedRootForAdapter(adapter) {
const homeDir = path.resolve('/__ecc_catalog_home__');
const projectRoot = path.resolve('/__ecc_catalog_project__');
const absoluteRoot = adapter.resolveRoot({ homeDir, projectRoot, env: {} });
const baseRoot = adapter.kind === 'home' ? homeDir : projectRoot;
const prefix = adapter.kind === 'home' ? '~/' : './';
return `${prefix}${path.relative(baseRoot, absoluteRoot).replace(/\\/g, '/')}`;
}
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}`View on GitHub (pinned to 8321021c54)