affaan-m/ECC · error · Error

Unknown install component: ${componentId}

Error message

Unknown install component: ${componentId}

What it means

Thrown by expandComponentIdsToModuleIds() when iterating componentIds inside resolveInstallPlan or any caller that expands a list. Unlike getInstallComponent, this path does not trim or normalize each ID — it looks up the raw value in componentsById and fails fast on a miss. It exists to surface a bad include/exclude list before any module is resolved.

Source

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

  return {
    id: component.id,
    family: component.family,
    description: component.description,
    moduleIds,
    moduleCount: moduleIds.length,
    targets: intersectTargets(modules),
    modules,
  };
}

function expandComponentIdsToModuleIds(componentIds, manifests) {
  const expandedModuleIds = [];

  for (const componentId of dedupeStrings(componentIds)) {
    const component = manifests.componentsById.get(componentId);
    if (!component) {
      throw new Error(`Unknown install component: ${componentId}`);
    }
    expandedModuleIds.push(...component.modules);
  }

  return dedupeStrings(expandedModuleIds);
}

function getTargetDefaultProfileId(target, manifests) {
  const profileId = target ? TARGET_DEFAULT_PROFILE_IDS[target] : null;
  return profileId && manifests.profiles[profileId] ? profileId : null;
}

function getTargetDefaultExclusions(target, manifests) {
  const exclusions = target ? TARGET_DEFAULT_EXCLUSIONS[target] : null;
  if (!Array.isArray(exclusions)) {
    return [];
  }

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Before resolveInstallPlan, filter the list through listInstallComponents() IDs.
  2. Use LOCALE_ALIAS_TO_COMPONENT_ID to map locale aliases to full 'locale:...' IDs.
  3. If you do not need expansion, pass options.moduleIds directly instead of component IDs.
  4. Print the unknown ID alongside listInstallComponents() output to spot the typo.

Example fix

// before
resolveInstallPlan({ includeComponentIds: ['lang:rust', 'lang:rst'] }); // typo
// after
const valid = new Set(listInstallComponents().map(c => c.id));
const includeComponentIds = ['lang:rust', 'lang:rst'].filter(id => valid.has(id));
resolveInstallPlan({ includeComponentIds });
Defensive patterns

Strategy: validation

Validate before calling

const known = new Set(listInstallComponents().map(c => c.id));
const safe = componentIds.filter(id => known.has(id));
if (safe.length !== componentIds.length) {
  const missing = componentIds.filter(id => !known.has(id));
  throw new Error(`Unknown component ids: ${missing.join(', ')}`);
}
resolveInstallPlan({ includeComponentIds: safe });

Prevention

When it happens

Trigger: Passing options.includeComponentIds or options.excludeComponentIds to resolveInstallPlan with one or more IDs that are not in install-components.json. Also triggered by direct calls to expandComponentIdsToModuleIds from custom tooling.

Common situations: A profile or shell script forwards a stale component list after an ECC version bump; a user mixes a locale alias ('ja') with a component ID ('locale:ja'); an include and exclude list reference the same typo differently.

Related errors


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