{"record":{"id":"084e37132a7e1faa","repo":"bmad-code-org/BMAD-METHOD","slug":"external-module-modulecode-not-found-in-the-b","errorCode":null,"errorMessage":"External module '${moduleCode}' not found in the BMad registry","messagePattern":"External module '(.+?)' not found in the BMad registry","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"tools/installer/modules/external-manager.js","lineNumber":215,"sourceCode":"  }\n\n  /**\n   * Clone an external module repository to cache, resolving the requested\n   * channel (stable / next / pinned) to a concrete git ref.\n   *\n   * @param {string} moduleCode - Code of the external module\n   * @param {Object} options - Clone options\n   * @param {boolean} [options.silent] - Suppress spinner output\n   * @param {Object} [options.channelOptions] - Parsed channel flags. See\n   *   modules/channel-plan.js. When absent, the module installs on its\n   *   registry-declared default channel (typically 'stable').\n   * @returns {string} Path to the cloned repository\n   */\n  async cloneExternalModule(moduleCode, options = {}) {\n    const moduleInfo = await this.getModuleByCode(moduleCode);\n\n    if (!moduleInfo) {\n      throw new Error(`External module '${moduleCode}' not found in the BMad registry`);\n    }\n\n    // Normalize to the canonical code so cache dir, in-memory resolutions,\n    // and log/error text stay consistent even when called with a renamed\n    // module's prior alias (getModuleByCode resolves aliases above).\n    moduleCode = moduleInfo.code;\n\n    const cacheDir = this.getExternalCacheDir();\n    const moduleCacheDir = path.join(cacheDir, moduleCode);\n    const silent = options.silent || false;\n\n    // Create cache directory if it doesn't exist\n    await fs.ensureDir(cacheDir);\n\n    // Helper to create a spinner or a no-op when silent\n    const createSpinner = async () => {\n      if (silent) {\n        return {","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/bmad-code-org/BMAD-METHOD/blob/b70486b9bdcb0a404d329e2a763b57964e7f1360/tools/installer/modules/external-manager.js#L197-L233","documentation":"Thrown by ExternalModuleManager.cloneExternalModule() when getModuleByCode() returns null — the provided moduleCode is not found in the bundled bmad-modules.yaml registry, neither as a current code nor as a registered alias. Every external module must be declared in the registry before it can be cloned.","triggerScenarios":"Calling cloneExternalModule('unknown-code') or cloneExternalModule('old-name') where 'old-name' was removed and not listed in any module's aliases array. The lookup checks m.code === code and m.aliases.includes(code).","commonSituations":"A module was renamed and the old code wasn't added to the aliases list; the user typed the wrong module code; the registry YAML is outdated or missing the module entry; the module was deprecated and removed entirely.","solutions":["Run the installer's module listing command to see available module codes.","Check bmad-modules.yaml for the correct module code.","If the module was renamed, find the new code and update your configuration.","If installing a custom module not in the registry, use the custom module URL install path instead."],"exampleFix":"// before\nawait extMgr.cloneExternalModule('old-module-name');\n\n// after\nawait extMgr.cloneExternalModule('new-module-name');\n// verify with:\n// const mods = await extMgr.listAvailable();\n// console.log(mods.map(m => m.code));","handlingStrategy":"validation","validationCode":"// Verify module exists in registry before cloning\nconst moduleInfo = await extMgr.getModuleByCode(moduleCode);\nif (!moduleInfo) {\n  const available = await extMgr.listAvailable();\n  const codes = available.map(m => m.code);\n  throw new Error(`Module '${moduleCode}' not found. Available: ${codes.join(', ')}`);\n}\nawait extMgr.cloneExternalModule(moduleCode, options);","typeGuard":null,"tryCatchPattern":"try {\n  await extMgr.cloneExternalModule(moduleCode, options);\n} catch (e) {\n  if (e.message.includes('not found in the BMad registry')) {\n    const mods = await extMgr.listAvailable();\n    console.error('Available modules:', mods.map(m => m.code).join(', '));\n  }\n  throw e;\n}","preventionTips":["List available modules before attempting to install by code.","Use the canonical module code from bmad-modules.yaml.","For custom modules not in the registry, use the URL-based custom install path."],"tags":["registry","external-modules","input-validation","configuration"],"backgroundTag":null,"analyzedSha":"b70486b9bdcb0a404d329e2a763b57964e7f1360","analyzedAt":"2026-08-13T01:21:12.247Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}