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

Module '${moduleName}' is not installed

Error message

Module '${moduleName}' is not installed

What it means

Thrown by OfficialModules.update after findModuleSource succeeded but fs.pathExists(bmadDir/moduleName) is false. The module's source is reachable but no installed copy exists at the target, so syncModule has nothing to update. Distinct from error 41: source resolves, target is missing.

Source

Thrown at tools/installer/modules/official-modules.js:442

      },
    };
  }

  /**
   * Update an existing module
   * @param {string} moduleName - Name of the module to update
   * @param {string} bmadDir - Target bmad directory
   */
  async update(moduleName, bmadDir) {
    const sourcePath = await this.findModuleSource(moduleName);
    const targetPath = path.join(bmadDir, moduleName);

    if (!sourcePath) {
      throw new Error(`Module '${moduleName}' not found in any source location`);
    }

    if (!(await fs.pathExists(targetPath))) {
      throw new Error(`Module '${moduleName}' is not installed`);
    }

    await this.syncModule(sourcePath, targetPath);

    return {
      success: true,
      module: moduleName,
      path: targetPath,
    };
  }

  /**
   * Remove a module
   * @param {string} moduleName - Name of the module to remove
   * @param {string} bmadDir - Target bmad directory
   */
  async remove(moduleName, bmadDir) {
    const targetPath = path.join(bmadDir, moduleName);

View on GitHub (pinned to b70486b9bd)

Solutions

  1. Run installer.install(moduleName, bmadDir) first to lay down the module, then update.
  2. Verify bmadDir is the correct absolute _bmad/ path containing the module directory.
  3. Check _bmad/manifest.json — if the module isn't listed, install is the correct action, not update.

Example fix

// before
//   await modules.update('bmm', bmadDir);  // -> Module 'bmm' is not installed
//
// after
//   await modules.install('bmm', bmadDir);
//   await modules.update('bmm', bmadDir);
Defensive patterns

Strategy: validation

Validate before calling

if (!(await modules.isInstalled(moduleName, bmadDir))) {
  await modules.install(moduleName, bmadDir);
}
await modules.update(moduleName, bmadDir);

Try / catch

try {
  await modules.update(moduleName, bmadDir);
} catch (e) {
  if (/is not installed/.test(e.message)) {
    await modules.install(moduleName, bmadDir);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling installer.update('somemodule', bmadDir) when bmadDir/somemodule was never installed, was removed out-of-band, or bmadDir points at the wrong location.

Common situations: Calling update instead of install for a new module; the module directory was deleted manually; wrong bmadDir passed (typo, relative path); install was interrupted leaving manifest but no directory.

Related errors


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