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

version is not available when nothing is installed

Error message

version is not available when nothing is installed

What it means

Thrown by the ExistingInstall.version getter when the installation snapshot reports installed=false. ExistingInstall.empty() (returned when no bmad dir or no core/modules/manifest are detected) always sets installed=false, so reading .version on it is undefined. The getter exists to fail fast rather than return null silently.

Source

Thrown at tools/installer/core/existing-install.js:25

 * Immutable snapshot of an existing BMAD installation.
 * Pure query object — no filesystem operations after construction.
 */
class ExistingInstall {
  #version;

  constructor({ installed, version, hasCore, modules, ides }) {
    this.installed = installed;
    this.#version = version;
    this.hasCore = hasCore;
    this.modules = Object.freeze(modules.map((m) => Object.freeze({ ...m })));
    this.moduleIds = Object.freeze(this.modules.map((m) => m.id));
    this.ides = Object.freeze([...ides]);
    Object.freeze(this);
  }

  get version() {
    if (!this.installed) {
      throw new Error('version is not available when nothing is installed');
    }
    return this.#version;
  }

  static empty() {
    return new ExistingInstall({
      installed: false,
      version: null,
      hasCore: false,
      modules: [],
      ides: [],
    });
  }

  /**
   * Scan a bmad directory and return an immutable snapshot of what's installed.
   * @param {string} bmadDir - Path to bmad directory
   * @returns {Promise<ExistingInstall>}

View on GitHub (pinned to b70486b9bd)

Solutions

  1. Check `existingInstall.installed` before reading `existingInstall.version` (mirror uninstall.js:65).
  2. If you need a display string, use `existingInstall.installed ? existingInstall.version : 'unknown'`.
  3. Ensure the directory passed to detect() actually contains a _bmad/ folder.

Example fix

// before
const install = await ExistingInstall.detect(bmadDir);
console.log(install.version);

// after
const install = await ExistingInstall.detect(bmadDir);
console.log(install.installed ? install.version : 'unknown');
Defensive patterns

Strategy: type-guard

Validate before calling

const install = await ExistingInstall.detect(bmadDir);
if (!install.installed) {
  // handle no-install case without reading .version
  return;
}

Type guard

function hasVersion(install) {
  return install instanceof ExistingInstall && install.installed === true;
}

Prevention

When it happens

Trigger: Calling `existingInstall.version` on an instance produced by `ExistingInstall.empty()`, or on any ExistingInstall where `detect()` found no core directory, no modules, and no manifest.yaml. Happens in code paths that skip the `existingInstall.installed` guard before reading version.

Common situations: Running uninstall/status/update commands against a directory that never had BMAD installed, or where _bmad/ was deleted by hand. A caller that assumes `.version` is always populated after `detect()`.

Related errors


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