{"record":{"id":"57b768771cde5131","repo":"affaan-m/ECC","slug":"unknown-install-component-normalizedcomponentid","errorCode":null,"errorMessage":"Unknown install component: ${normalizedComponentId}","messagePattern":"Unknown install component: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/install-manifests.js","lineNumber":409,"sourceCode":"        moduleIds,\n        moduleCount: moduleIds.length,\n        targets,\n      };\n    })\n    .filter(component => !target || component.targets.includes(target));\n}\n\nfunction getInstallComponent(componentId, options = {}) {\n  const manifests = loadInstallManifests(options);\n  const normalizedComponentId = String(componentId || '').trim();\n\n  if (!normalizedComponentId) {\n    throw new Error('An install component ID is required');\n  }\n\n  const component = manifests.componentsById.get(normalizedComponentId);\n  if (!component) {\n    throw new Error(`Unknown install component: ${normalizedComponentId}`);\n  }\n\n  const moduleIds = dedupeStrings(component.modules);\n  const modules = moduleIds\n    .map(moduleId => manifests.modulesById.get(moduleId))\n    .filter(Boolean)\n    .map(module => ({\n      id: module.id,\n      kind: module.kind,\n      description: module.description,\n      targets: module.targets,\n      defaultInstall: module.defaultInstall,\n      cost: module.cost,\n      stability: module.stability,\n      dependencies: dedupeStrings(module.dependencies),\n    }));\n\n  return {","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/install-manifests.js#L391-L427","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Call listInstallComponents({ target }) to print the exact valid IDs for this checkout.","Verify the family prefix matches COMPONENT_FAMILY_PREFIXES: baseline:, lang:, framework:, capability:, agent:, skill:, locale:.","If referencing a skill, use the synthetic ID 'skill:<skill-dir-name>' exactly as it appears under skills/.","Confirm manifests/install-components.json exists at the repoRoot you passed in options.repoRoot."],"exampleFix":"// before\ngetInstallComponent('skills:tdd'); // wrong prefix + plural\n// after\ngetInstallComponent('skill:tdd-workflow');","handlingStrategy":"validation","validationCode":"const known = new Set(listInstallComponents().map(c => c.id));\nif (!known.has(componentId)) {\n  throw new Error(`Unknown component id: ${componentId}. Valid: ${[...known].slice(0, 10).join(', ')}...`);\n}\nconst info = getInstallComponent(componentId);","typeGuard":"/** @param {string} id @param {Set<string>} known */\nfunction isKnownComponentId(id, known) {\n  return typeof id === 'string' && known.has(id);\n}","tryCatchPattern":"try {\n  return getInstallComponent(componentId);\n} catch (err) {\n  if (/^Unknown install component:/.test(err.message)) {\n    return { notFound: true, id: componentId };\n  }\n  throw err;\n}","preventionTips":["Cache listInstallComponents() output and validate before lookup.","Use LOCALE_ALIAS_TO_COMPONENT_ID to convert locale aliases to full 'locale:...' ids."],"tags":["install","validation","lookup","manifest"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}