nomuraya — The Curious Operator

Hands-on accounts of building, breaking, and rebuilding AI agents.

The reason why the Mac development environment was broken every time it was "brew upgrade" and what I stopped doing

2026-06-17

He is an engineer who helps companies implement AI, and has been using Macs for nearly 10 years while running multiple projects side by side.The environment was broken with every `brew upgrade`.

It was repaired every time it broke.Fixed it and broke it again.At the point of three repetitions, we examined "why it breaks".Once I knew the cause, it seemed foolish to keep fixing it, so I switched to a different method.

This article describes what I did while explaining to non-engineers why this happened.

What is brew

It's like an app installer that an engineer on a Mac uses to “put in a tool.”Its official name is Homebrew.

The App Store is where apps are distributed to the general public on iPhone and Mac, but the command-line tools used by developers are often missing from the App Store, and brew fills the gap.Just open the terminal and hit `brew install tool name`.

The community you manage regularly updates each tool, so you can hit the command `brew upgrade` to get the latest version.It is certainly convenient to manage all brews to update them in bulk, and the habit of "brewing when putting tools in for the time being" naturally took root among developers.

I was one of them.Tools for operating AWS on a Mac, a JavaScript execution environment called Node.js, and a programming language called Python —— all were put in brew.I wanted to maintain an orderly environment by gathering management in one place.

The problem is that brew isn't for every tool.

Why it broke - Structural problem of "sharing parts"

Explain with a little metaphor.

many of the tools managed by brew work behind the scenes using another tool called Python.So is the AWS CLI (a tool that operates a cloud service called AWS).

This is easy to understand by comparing it to an apartment building.

Each room (tool) seems to be independent, but in fact it operates using the common facilities of the building (Python).When the version of common facilities changes, the room facilities that were made accordingly will not be suitable.

running `brew upgrade` on brew may cause the Python version to go up.It changed from 3.11 to 3.12.Until then, the AWS CLI, which operated on the premise of "working with Python 3.11", stopped working the moment 3.11 disappeared.

Here's the error.

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

"There's no 3.11," he says.Of course, it disappeared with the brew upgrade.

Why 'brew for now' is a problem

brew has "Python managed by brew itself".Multiple tools share that Python.

Python is like a “common engine for moving tools.”Both the AWS CLI and many tools run internally using Python, and when you put them in via brew, everyone uses a common engine called brew-managed Python.

The problem is that Python will also be upgraded.3.11 becomes 3.12.3.12 becomes 3.13.When the common engine is new, the tools that were running on the premise of the old version will not work.The main screen of the stadium that used to be used will no longer support the remote control that disappeared due to the equipment update.

The AWS CLI has a dedicated installer that AWS has officially created.With this installer, the AWS CLI has its own Python inside.Imagine having your own electric kettle in your room, no matter how many versions of brew Python you've switched to, instead of using the apartment's shared amenities.

I didn't know this, but I put in the AWS CLI with "brew for now".It had a structure that used common facilities.So it broke.

It looked like "centralized management", but it was actually a weakness

the intuition that it is easy to manage everything with brew is partly correct.However, "managing large tools via brew" means "more tools that rely on shared facilities".

Each time a common facility is updated, the tools that depend on the facility may become chained and stuck.The more tools you have, the more risk you take.Looking at the centralized management, the reality was only that "fragile dependencies are collected in one place".

Similar structures are sometimes seen at sites that support the introduction of AI.The policy of "do it all with this tool" is actually based on a specific external dependence, and the whole thing stops the moment the dependence changes.I thought that unification would bring stability, and it was creating a single point of failure.

What did you change? - Switch to Expert Tools

After organizing, I changed the person in charge for each tool.

AWS CLI and Sam CLI (Amazon's serverless development tool) were moved to an installer officially distributed by AWS.It is now out of brew control and no longer relies on brew's Python.

Node.js (the mechanism for running JavaScript) was moved to a tool called volta. volta specializes in version control of Node.js and automatically uses the appropriate version for each project. When you manage Node.js in brew, you can not respond when the versions of multiple projects are mixed.

Python has a tool called uv, which takes care of everything from installing Python to managing packages. The concept of brew Python becomes unnecessary in the first place.

What we have left behind is what brew is originally good at - CLI tools and libraries with simple dependencies, such as jq, gh, and ffmpeg.

To summarize the state of the organization:

| My Tools | How to Manage | |-----------|---------| | AWS CLI, Sam CLI | Official Installer | | Node.js | volta | | Python | uv | | jq, gh, ffmpeg, etc. | brew (business as usual) |

The same story for non-engineers

Some people may have read this far and thought, "It doesn't matter to me."However, problems with the same structure occur on a daily basis even outside of software.

There is a shared office printer.Everybody uses it.If the printer breaks, everyone stops working.To prevent that, frequent users put printers on their desks.It is a decision to "reduce reliance on shared facilities."

Suppose the water heater in the apartment was shared by all residents.There is only one water heater, so all rooms cannot use hot water at the time of repair or replacement.The more tenants, the higher the risk.The solution is to install separate water heaters in each room, which is the same idea as "letting large tools have their own Python".

What was happening in the development environment of the Mac was the same structure: too many tools relied on a common facility called brew.Chain broke every time a shared facility (Python) was updated.

The solution was to “move things that are not suitable for sharing to a dedicated facility.”

The important thing is not to "centrally manage everything" but to separate the "what and where to manage" according to the purpose.It is more valuable in practical terms to be less fragile than it is to be neat in appearance.

I'm no longer afraid of brew upgrades

Before the change, I was hesitant to perform the `brew upgrade`.I didn't know what would break.

After it actually broke, I got into the habit of procrastinating the upgrade.It's like, "Don't update."Stopping updates, including security fixes, is a risk in itself.But the fear of breaking prevailed.There was a bad cycle of accumulating→ security risks that failed to update.

After the change, you can perform the upgrade without thinking about anything.Python and Node.js are out of brew management, so there are almost no dependencies that are chained and broken by upgrade.

The time and energy I was spending on the "I'll fix it if it breaks" cycle disappeared.This change seems modest, but there is a big difference in the cost of experience when stacked together.It changed from "preparation for breaking" to "concentration on moving".

Regular software updates are close to home ventilation and regular inspections.If you don't do it because it is troublesome, it becomes a big problem when you realize it.Creating a state where you can renew without fear is a surprisingly important environmental design.

Opportunity to revisit "Something I've started using"

there are many choices, not only brew, "I continue to use it because I did it first".Even choices that were rational at first can be irrational when circumstances change.

The same thing happens with smartphones.I kept using the first app I put in for years, and when I realized it, I kept eating storage.I was in the habit of checking every time I received a notification, and my concentration was interrupted.Having the habit of doubting “because I did it in the first place” reveals small everyday inefficiencies.

Back to Brew as a Mac tool, when you hit the command `brew list`, the package list of brew management will appear.If you can't explain why you're putting it in via brew, it's a candidate for review.If you're an engineer, I suggest you check it out.

Even for non-engineers, the question “Why does this habit continue?” is worth asking on a regular basis.Do you continue to use it because it is convenient, or have you never considered another option?In the latter case, the review may lead to unexpected improvements.

Wrap-up

Organizing what happened and how to deal with it is simple.

i was managing large tools such as AWS CLI via brew.These used a shared facility called Python inside brew.The tool broke every time Python upgraded.After fixing it, the same thing happened again.

I stopped brewing for the time being.For large tools, go to the official installer of the product.To manage Python, go to uv.Manage Node.js to volta.I transferred each to a specialist.

brew left only CLI tools with simple dependencies.

It's not broken.I'm no longer afraid of updates.The time and energy I used for restoration can now be used for different things.

It's a waste of time to fix every time the environment breaks down.Once you consider "why are you putting it in via brew", it may be a simpler and harder configuration to break.

Reference: - [AWS CLI Official Installation Guide] (https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) - [volta official documentation] (https://volta.sh/) - [uv official documentation] (https://docs.astral.sh/uv/)

Reference: - [AWS CLI Official Installation Guide] (https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) - [volta official documentation] (https://volta.sh/) - [uv official documentation] (https://docs.astral.sh/uv/)

---

*Machine-translated (MyMemory API) from a Japanese original at [nomuraya-hub.pages.dev](https://nomuraya-hub.pages.dev/). Pre-review draft. I am the same author writing under different pen names — "nomuraya / shimajima / 中翔" — depending on the medium.*

Subscribe

If you want occasional long-form posts about AI agents, FIRE, and how a curious operator thinks about both, drop your email below.

Subscribe via Substack →