{"record":{"id":"edafaab59c334398","repo":"affaan-m/ECC","slug":"unknown-install-component-componentid","errorCode":null,"errorMessage":"Unknown install component: ${componentId}","messagePattern":"Unknown install component: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/install-manifests.js","lineNumber":444,"sourceCode":"\n  return {\n    id: component.id,\n    family: component.family,\n    description: component.description,\n    moduleIds,\n    moduleCount: moduleIds.length,\n    targets: intersectTargets(modules),\n    modules,\n  };\n}\n\nfunction expandComponentIdsToModuleIds(componentIds, manifests) {\n  const expandedModuleIds = [];\n\n  for (const componentId of dedupeStrings(componentIds)) {\n    const component = manifests.componentsById.get(componentId);\n    if (!component) {\n      throw new Error(`Unknown install component: ${componentId}`);\n    }\n    expandedModuleIds.push(...component.modules);\n  }\n\n  return dedupeStrings(expandedModuleIds);\n}\n\nfunction getTargetDefaultProfileId(target, manifests) {\n  const profileId = target ? TARGET_DEFAULT_PROFILE_IDS[target] : null;\n  return profileId && manifests.profiles[profileId] ? profileId : null;\n}\n\nfunction getTargetDefaultExclusions(target, manifests) {\n  const exclusions = target ? TARGET_DEFAULT_EXCLUSIONS[target] : null;\n  if (!Array.isArray(exclusions)) {\n    return [];\n  }\n","sourceCodeStart":426,"sourceCodeEnd":462,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/install-manifests.js#L426-L462","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Before resolveInstallPlan, filter the list through listInstallComponents() IDs.","Use LOCALE_ALIAS_TO_COMPONENT_ID to map locale aliases to full 'locale:...' IDs.","If you do not need expansion, pass options.moduleIds directly instead of component IDs.","Print the unknown ID alongside listInstallComponents() output to spot the typo."],"exampleFix":"// before\nresolveInstallPlan({ includeComponentIds: ['lang:rust', 'lang:rst'] }); // typo\n// after\nconst valid = new Set(listInstallComponents().map(c => c.id));\nconst includeComponentIds = ['lang:rust', 'lang:rst'].filter(id => valid.has(id));\nresolveInstallPlan({ includeComponentIds });","handlingStrategy":"validation","validationCode":"const known = new Set(listInstallComponents().map(c => c.id));\nconst safe = componentIds.filter(id => known.has(id));\nif (safe.length !== componentIds.length) {\n  const missing = componentIds.filter(id => !known.has(id));\n  throw new Error(`Unknown component ids: ${missing.join(', ')}`);\n}\nresolveInstallPlan({ includeComponentIds: safe });","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate include/exclude component lists against listInstallComponents() before resolveInstallPlan.","Keep a single source of truth for component ids; do not hardcode in multiple places."],"tags":["install","validation","lookup","manifest","dependency-resolution"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}