affaan-m/ECC · error · Error

Unknown install component: ${normalizedComponentId}

Error message

Unknown install component: ${normalizedComponentId}

What it means

Thrown by getInstallComponent() after the empty-ID guard passes but the normalized ID is not a key in manifests.componentsById. That map is built from manifests/install-components.json plus synthetic skill: components generated by addSyntheticSkillComponents. A miss means the ID is spelled wrong, prefixed wrong, or genuinely absent from this repo version.

Source

Thrown at scripts/lib/install-manifests.js:409

        moduleIds,
        moduleCount: moduleIds.length,
        targets,
      };
    })
    .filter(component => !target || component.targets.includes(target));
}

function getInstallComponent(componentId, options = {}) {
  const manifests = loadInstallManifests(options);
  const normalizedComponentId = String(componentId || '').trim();

  if (!normalizedComponentId) {
    throw new Error('An install component ID is required');
  }

  const component = manifests.componentsById.get(normalizedComponentId);
  if (!component) {
    throw new Error(`Unknown install component: ${normalizedComponentId}`);
  }

  const moduleIds = dedupeStrings(component.modules);
  const modules = moduleIds
    .map(moduleId => manifests.modulesById.get(moduleId))
    .filter(Boolean)
    .map(module => ({
      id: module.id,
      kind: module.kind,
      description: module.description,
      targets: module.targets,
      defaultInstall: module.defaultInstall,
      cost: module.cost,
      stability: module.stability,
      dependencies: dedupeStrings(module.dependencies),
    }));

  return {

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Call listInstallComponents({ target }) to print the exact valid IDs for this checkout.
  2. Verify the family prefix matches COMPONENT_FAMILY_PREFIXES: baseline:, lang:, framework:, capability:, agent:, skill:, locale:.
  3. If referencing a skill, use the synthetic ID 'skill:<skill-dir-name>' exactly as it appears under skills/.
  4. Confirm manifests/install-components.json exists at the repoRoot you passed in options.repoRoot.

Example fix

// before
getInstallComponent('skills:tdd'); // wrong prefix + plural
// after
getInstallComponent('skill:tdd-workflow');
Defensive patterns

Strategy: validation

Validate before calling

const known = new Set(listInstallComponents().map(c => c.id));
if (!known.has(componentId)) {
  throw new Error(`Unknown component id: ${componentId}. Valid: ${[...known].slice(0, 10).join(', ')}...`);
}
const info = getInstallComponent(componentId);

Type guard

/** @param {string} id @param {Set<string>} known */
function isKnownComponentId(id, known) {
  return typeof id === 'string' && known.has(id);
}

Try / catch

try {
  return getInstallComponent(componentId);
} catch (err) {
  if (/^Unknown install component:/.test(err.message)) {
    return { notFound: true, id: componentId };
  }
  throw err;
}

Prevention

When it happens

Trigger: Passing an ID that exists in a different repo/checkout, using the wrong family prefix (e.g. 'skills:tdd' instead of 'skill:tdd-workflow'), trailing characters, case mismatch, or referencing a component that was renamed or removed in a newer ECC version.

Common situations: Hardcoded component IDs drift after an upgrade; docs/examples reference an old name; user typo; the component is locale-prefixed (e.g. 'locale:ja') and the alias resolver was bypassed; the manifests JSON is missing or partial because of a bad clone.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/57b768771cde5131. Report an issue: GitHub.