jdx/mise · error

brew is not available

Error message

brew is not available: {}

What it means

The brew branch of `mise bootstrap packages prune` first checks that Homebrew is usable via `BrewManager::is_available()`; if not, it fails with the manager's own unavailable reason (missing binary, bad prefix, unsupported platform). Pruning needs brew because it must query and uninstall actual formulae.

Solutions

  1. Install or repair Homebrew so `brew --version` succeeds in the same shell mise runs in.
  2. Add brew's bin directory to PATH (e.g. `eval "$(/opt/homebrew/bin/brew shellenv)"`).
  3. If brew packages are managed elsewhere, exclude brew via `[system_packages] managers` and prune a different manager.

Example fix

// before
$ mise bootstrap packages prune --manager brew
error: brew is not available: brew not found on PATH

// after
$ eval "$(/opt/homebrew/bin/brew shellenv)"
$ mise bootstrap packages prune --manager brew
Defensive patterns

Strategy: fallback

Validate before calling

command -v brew >/dev/null 2>&1 || { echo "brew missing; cannot prune"; exit 1; }
brew --version >/dev/null || { echo "brew broken"; exit 1; }

Try / catch

try {
  await run("mise", ["bootstrap","packages","prune","--manager","brew"]);
} catch (e) {
  if (/brew is not available/.test(e.message)) {
    // install/repair Homebrew or exclude brew from pruning
  } else throw e;
}

Prevention

When it happens

Trigger: Running `mise bootstrap packages prune --manager brew` on a machine without Homebrew, with `brew` not on PATH, or with a broken Homebrew installation.

Common situations: Linux hosts without Homebrew; macOS systems where the command-line tools/Homebrew prefix moved (e.g. Intel→Apple Silicon migration); CI images lacking brew; PATH not including `/opt/homebrew/bin`.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/1e692afb7d0a2b79. Report an issue: GitHub.

Appendix: source

Thrown at src/cli/system/prune.rs:133

        }
        if !self.yes && !Settings::get().yes && console::user_attended_stderr() {
            let msg = format!("{}: prune {}?", self.manager, remove.join(", "));
            if !prompt::confirm(msg)?.is_yes() {
                info!("{}: skipped", self.manager);
                return Ok(());
            }
        }
        let removed = manager.apply_prune_plan(&plan).await?;
        info!("{}: pruned {removed} packages", self.manager);
        Ok(())
    }

    #[cfg(unix)]
    async fn run_brew(self) -> Result<()> {
        debug_assert_eq!(self.manager, "brew");
        let manager = brew::BrewManager::new();
        if !manager.is_available() {
            bail!("brew is not available: {}", manager.unavailable_reason());
        }
        let config = Config::get().await?;
        let packages = system::packages_from_config_and_tracked_config_files(&config).await?;
        let mut configured = packages
            .iter()
            .find(|mp| mp.manager.name() == "brew")
            .map(|mp| mp.requests.clone())
            .unwrap_or_default();
        let configured_casks = packages
            .iter()
            .find(|mp| mp.manager.name() == "brew-cask")
            .map(|mp| mp.requests.as_slice())
            .unwrap_or_default();
        configured.extend(brew::cask_formula_dependencies(configured_casks).await?);
        let plan = brew::prune_plan(&configured).await?;
        if plan.is_empty() {
            info!("brew: nothing to prune");
            return Ok(());

View on GitHub (pinned to 533346cc37)