bmad-code-org/BMAD-METHOD · error · Error

External module '${moduleCode}' not found in the BMad regist

Error message

External module '${moduleCode}' not found in the BMad registry

What it means

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.

Source

Thrown at tools/installer/modules/external-manager.js:215

  }

  /**
   * Clone an external module repository to cache, resolving the requested
   * channel (stable / next / pinned) to a concrete git ref.
   *
   * @param {string} moduleCode - Code of the external module
   * @param {Object} options - Clone options
   * @param {boolean} [options.silent] - Suppress spinner output
   * @param {Object} [options.channelOptions] - Parsed channel flags. See
   *   modules/channel-plan.js. When absent, the module installs on its
   *   registry-declared default channel (typically 'stable').
   * @returns {string} Path to the cloned repository
   */
  async cloneExternalModule(moduleCode, options = {}) {
    const moduleInfo = await this.getModuleByCode(moduleCode);

    if (!moduleInfo) {
      throw new Error(`External module '${moduleCode}' not found in the BMad registry`);
    }

    // Normalize to the canonical code so cache dir, in-memory resolutions,
    // and log/error text stay consistent even when called with a renamed
    // module's prior alias (getModuleByCode resolves aliases above).
    moduleCode = moduleInfo.code;

    const cacheDir = this.getExternalCacheDir();
    const moduleCacheDir = path.join(cacheDir, moduleCode);
    const silent = options.silent || false;

    // Create cache directory if it doesn't exist
    await fs.ensureDir(cacheDir);

    // Helper to create a spinner or a no-op when silent
    const createSpinner = async () => {
      if (silent) {
        return {

View on GitHub (pinned to b70486b9bd)

Solutions

  1. Run the installer's module listing command to see available module codes.
  2. Check bmad-modules.yaml for the correct module code.
  3. If the module was renamed, find the new code and update your configuration.
  4. If installing a custom module not in the registry, use the custom module URL install path instead.

Example fix

// before
await extMgr.cloneExternalModule('old-module-name');

// after
await extMgr.cloneExternalModule('new-module-name');
// verify with:
// const mods = await extMgr.listAvailable();
// console.log(mods.map(m => m.code));
Defensive patterns

Strategy: validation

Validate before calling

// Verify module exists in registry before cloning
const moduleInfo = await extMgr.getModuleByCode(moduleCode);
if (!moduleInfo) {
  const available = await extMgr.listAvailable();
  const codes = available.map(m => m.code);
  throw new Error(`Module '${moduleCode}' not found. Available: ${codes.join(', ')}`);
}
await extMgr.cloneExternalModule(moduleCode, options);

Try / catch

try {
  await extMgr.cloneExternalModule(moduleCode, options);
} catch (e) {
  if (e.message.includes('not found in the BMad registry')) {
    const mods = await extMgr.listAvailable();
    console.error('Available modules:', mods.map(m => m.code).join(', '));
  }
  throw e;
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of bmad-code-org/BMAD-METHOD@b70486b9bd (2026-08-13). Data as JSON: /api/errors/084e37132a7e1faa. Report an issue: GitHub.