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

No valid actions available for this installation

Error message

No valid actions available for this installation

What it means

Thrown in --yes non-interactive mode when the choices array is empty. Under normal flow 'update' is always pushed for an existing install, so choices is empty only in a defensive edge case — e.g. _bmad/ exists but getExistingInstallation reports no install info, leaving no action to default to.

Source

Thrown at tools/installer/ui.js:302

      }

      // Common actions
      choices.push({ name: 'Modify BMAD Installation', value: 'update' });

      // Check if action is provided via command-line
      if (options.action) {
        const validActions = choices.map((c) => c.value);
        if (!validActions.includes(options.action)) {
          throw new Error(`Invalid action: ${options.action}. Valid actions: ${validActions.join(', ')}`);
        }
        actionType = options.action;
        await prompts.log.info(`Using action from command-line: ${actionType}`);
      } else if (options.yes) {
        // Default to quick-update if available, unless flags that require the
        // full update path are present (e.g. --custom-source which re-clones
        // modules at a new version — quick-update skips that entirely).
        if (choices.length === 0) {
          throw new Error('No valid actions available for this installation');
        }
        const hasQuickUpdate = choices.some((c) => c.value === 'quick-update');
        const needsFullUpdate = !!options.customSource;
        actionType = hasQuickUpdate && !needsFullUpdate ? 'quick-update' : (choices.find((c) => c.value === 'update') || choices[0]).value;
        await prompts.log.info(`Non-interactive mode (--yes): defaulting to ${actionType}`);
      } else {
        actionType = await prompts.select({
          message: 'How would you like to proceed?',
          choices: choices,
          default: choices[0].value,
        });
      }

      // Handle quick update separately
      if (actionType === 'quick-update') {
        // Quick update never shows the module picker, so this is the only
        // place an existing install of a deprecated module hears about it.
        await this._warnDeprecatedModules(existingInstall.moduleIds || []);

View on GitHub (pinned to b70486b9bd)

Solutions

  1. Run without --yes to see the interactive menu and which actions (if any) are offered.
  2. Inspect _bmad/ — if it's a stale/partial artifact, remove it and run a fresh install.
  3. If it persists on a clean directory, report it — this branch is defensive and shouldn't trigger under normal state.
Defensive patterns

Strategy: try-catch

Validate before calling

if (options.yes && !hasExistingInstall) {
  console.error('--yes requires an existing install or an explicit --action; no actions are available.');
  process.exit(1);
}

Try / catch

try {
  await ui.run(options);
} catch (e) {
  if (/No valid actions available/.test(e.message)) {
    // inspect _bmad/; if stale, remove and run a fresh install without --yes
  } else { throw e; }
}

Prevention

When it happens

Trigger: Running with --yes against an installation where _bmad/ is detected but neither quick-update nor update was pushed onto choices (corrupted/partial install state).

Common situations: Stale/partial _bmad/ artifact that registers as existing but yields no install info; an interrupted prior install left a directory but no manifest.

Related errors


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