DEV Community

Sho Naka
Sho Naka

Posted on

My Mac dev environment broke on every brew upgrade. Here's the shared-dependency bug I kept fixing wrong.

I fixed the same crash after brew upgrade three times before I asked why it kept happening. Each time I patched the symptom. On the fourth break, I traced it to one shared runtime buried inside Homebrew.

TL;DR: Homebrew installs many CLI tools with a shared, brew-managed Python underneath them. When brew upgrade moves that Python forward, every tool still pointing at the old version breaks at once. The fix isn't "upgrade less" — it's giving each tool its own dedicated runtime instead of the shared one.

What actually happened

I'd been using Homebrew as the default for everything on my Mac for years — AWS CLI, Node.js, Python, all installed the same way, all kept up to date with one command: brew upgrade. Centralizing installs under one tool felt like good hygiene.

Then AWS CLI stopped working, right after a routine brew upgrade:

/opt/homebrew/bin/aws: /opt/homebrew/opt/python@3.11/bin/python3.11: bad interpreter: No such file or directory
Enter fullscreen mode Exit fullscreen mode

I reinstalled AWS CLI. It worked. A few weeks later, another brew upgrade, same error, different Python version number in the path. I fixed it again. Third time, same pattern. That's when I stopped patching and started asking why.

The number that changed my mind

The answer was in the error message the whole time: python@3.11. AWS CLI installed via Homebrew doesn't ship its own Python — it runs on whichever Python version Homebrew currently manages. When brew upgrade moved Python from 3.11 to 3.12, Homebrew removed the 3.11 binary. AWS CLI was still hard-linked to it. Gone runtime, broken tool.

This wasn't AWS CLI-specific. It was structural: Homebrew's own Python is a shared dependency, and every large tool installed through Homebrew that happens to run on Python was quietly built on top of that same shared thing.

Here's what I moved, and where, after tracing the actual dependency for each:

Tool Before After
AWS CLI, SAM CLI Homebrew Official AWS/SAM installer (bundles its own Python)
Node.js Homebrew volta (per-project version switching)
Python itself Homebrew uv
jq, gh, ffmpeg Homebrew Homebrew (unchanged — no shared-runtime dependency)

Three tools moved off Homebrew's shared Python entirely. The fourth category — simple CLI tools with no runtime dependency — stayed exactly where it was, because Homebrew is a legitimately good fit for those.

The rule I extracted

The instinct "manage everything in one place for simplicity" was backwards for tools with runtime dependencies. Centralizing installs didn't reduce risk — it concentrated it. Every tool riding on Homebrew's shared Python was one Python upgrade away from breaking at the same time.

Consolidation isn't the same as stability. It just means more things share one point of failure.

The distinction that mattered wasn't "brew vs. not brew." It was: does this tool carry its own runtime, or does it silently borrow Homebrew's? AWS CLI, Node, and Python-the-language all fall into "borrows a shared runtime that also gets upgraded out from under it." jq/gh/ffmpeg don't — they're closer to static binaries with no such dependency, so Homebrew stays the right tool for them.

Try it yourself

Run brew list and go down the list. For each large tool, ask: does this thing run inside something Homebrew also manages and upgrades independently — most often Python or Node? If yes, that's the candidate for moving to a dedicated, tool-specific installer or version manager.

What's the smallest dependency chain you can trace before you find the shared piece that's one upgrade away from taking three unrelated tools down with it?


Sho Naka (nomurasan). I help companies adopt AI day to day and run several projects on one Mac at once — this is one of the environment problems that came out of that.

This piece was adapted from a Japanese essay, with AI assistance for the cross-language rewrite. The reasoning, data, and conclusions are mine.

Originally published in Japanese at note.com/nomuraya. I write under "nomuraya / shimajima / 中翔" — the same person across media.

Top comments (0)