macOS runner: Homebrew "Error: ... already installed" in CI
The GitHub-hosted macOS image already ships many formulae, so brew install <name> fails with "already installed" instead of being a no-op. Use upgrade-or-install logic, not a bare install.
What this error means
A brew install step on macos-latest stops with "Error: <formula> X.Y is already installed" and a non-zero exit, even though nothing is actually wrong with the package.
Error: node 22.4.0 is already installed
To upgrade to 22.5.0, run:
brew upgrade nodeCommon causes
The runner image preinstalls the formula
GitHub-hosted macOS runners bake in popular tools (node, python, git). A bare brew install for one of them is treated as an error, not a no-op.
A previous step in the same job already installed it
If an earlier step installed the formula, a later plain brew install of the same name fails the same way.
How to fix it
Install only if missing, otherwise upgrade
- Replace bare
brew installwith a guard that tolerates a pre-installed formula. - Use
brew listto test presence, orbrew install || brew upgrade. - Re-run; the step now succeeds whether or not the formula was present.
brew list node >/dev/null 2>&1 || brew install node
brew upgrade node || truePrefer the preinstalled tool
If the runner already provides the tool at a workable version, skip the brew step entirely and use what the image ships.
node --version # use the image-provided node, no brew neededHow to prevent it
- Never use bare
brew installfor tools the image may already ship. - Guard installs with
brew list <name> ||so re-runs are idempotent. - Check the runner image manifest for what is preinstalled.