你的 README(專案首頁的說明)開頭,大概會教人怎麼安裝。那行安裝指令,你自己照著跑過幾次?
6 月 7 日下午 5 點 06 分,使用者 teddy123434 在 usage(我做的開源小工具,顯示 Claude Code、Codex 這兩個 AI 寫程式工具用了多少額度)開了 issue(問題回報)#32,標題是:
brew install 失敗:Errno::ENOENT: No such file or directory - usage.app
usage 在 Mac 上有一種裝法,是用 Homebrew(Mac 上裝軟體的工具)。Homebrew 每裝一個軟體,都照一份安裝說明檔來做,這份檔案叫 formula,寫著去哪裡下載、下載完放到哪裡。usage 的 formula 放在另一個 GitHub repo,這種 repo 叫 tap。
他打了 brew install aqua5230/homebrew-usage/usage,得到上面那行錯誤:找不到 usage.app。
他不只回報,還寫了原因。usage 的安裝檔是一個 zip,解開後最上層只有一個 usage.app 資料夾。Homebrew 遇到這種 zip,會自己走進那個資料夾。formula 接著說「把 usage.app 裝過去」,可是這時已經站在 usage.app 裡面,所以找不到。
他說,問題出在 formula 裡的這一行:
prefix.install "usage.app"
prefix 是 Homebrew 替這個軟體準備的資料夾,裝好的東西都放在這裡,例如 /opt/homebrew/Cellar/usage/0.16.1。這一行的意思是:把 usage.app 放進這個資料夾。他建議改成這樣:
prefix.install buildpath/"usage.app"
buildpath 是安裝進行時的工作資料夾,也就是 Homebrew「現在站的地方」。
我照他的建議改了 tap 裡的這一行,發出 v0.16.1,回他:採用你建議的修法,已在 v0.16.1 修正,重新安裝即可。從他開 issue 到我回覆,38 分鐘。
6 月 9 日清晨 5 點 39 分,另一位使用者開了 issue #34。他在一台乾淨的電腦上跑同一行指令,得到:
Errno::ENOENT: No such file or directory - /private/tmp/usage-20260609-91591-id48df/usage.app/usage.app
這次找不到的,是 usage.app 裡面的 usage.app。
他也附了原因:Homebrew 走進資料夾之後,buildpath 指的就是 usage.app 裡面。所以 buildpath/"usage.app",等於叫 Homebrew 在 usage.app 裡面再找一個 usage.app。
回頭看 #32:原因他寫對了,原文就寫著「工作目錄已經在 usage.app/ 內部,找不到 usage.app/usage.app」。修法卻沒跟上。
當天晚上,formula 改成另一種寫法,不再去找 usage.app(下一節實跑)。9 分鐘後,再改用 Cask(Homebrew 專門裝 App 的另一種安裝說明檔,會把 App 直接放進「應用程式」資料夾),我回覆並關掉 #34。
寫這篇時,我想親眼看到這兩個錯誤。我在本機建了一個暫用的 tap,放三份 formula。三份都下載 v0.16.1 的 zip,只有安裝那一行不一樣:
prefix.install "usage.app",是第一版到 v0.16.0 的寫法。跑出 Errno::ENOENT: No such file or directory - usage.app,跟 #32 一字不差。prefix.install buildpath/"usage.app",是 #32 建議的寫法。跑出的錯誤結尾是 usage.app/usage.app,跟 #34 一樣。(prefix/"usage.app").install Dir["*"],是 6 月 9 日晚上那一版。裝好了。第三種的意思是:在要安裝的地方開一個新的 usage.app 資料夾,把「現在站的這個資料夾裡的所有東西」放進去。它不去找 usage.app,因為它已經站在裡面。

Homebrew 的原始碼也寫了這件事:下載的檔案解開後,如果只有一個資料夾,就先走進去,再執行 formula 的安裝步驟。所以這個錯跟電腦乾不乾淨無關。
既然錯在寫法、不在電腦,那它是從哪一版開始的?
5 月 25 日晚上 8 點 44 分,tap 放上第一版 formula,安裝那一行就是第一種寫法。到 6 月 9 日改用 Cask 之前,formula 一共指向過 32 個版本。
我把這 32 個版本的 zip 都打開看,最上層都只有一個 usage.app 資料夾。我再拿第一版 formula,只把名稱改掉(避免跟其他軟體撞名),跑一次:
Errno::ENOENT: No such file or directory - usage.app
也就是說,從 5 月 25 日到 6 月 9 日晚上改寫之前,照 formula 裝 usage,每一版都會失敗。
Day 24 那位使用者,是 8 月用 Homebrew 裝好 App 之後,照 App 上的提示打指令才出錯。6 月 9 日以前照 README 用 Homebrew 裝的人,連 App 都拿不到。
這段時間,這行指令出現在這些地方:
brew tap aqua5230/homebrew-usage,再跑這行 brew install。brew install aqua5230/homebrew-usage/usage。
#32 那 38 分鐘裡,修法讀起來很合理:回報者的分析對,建議的寫法看起來只是把位置寫得更明白。答案其實就在他的分析裡:他寫了工作目錄已經在 usage.app 裡面,而 buildpath 就是這個工作目錄。讀的時候,這兩件事沒對上。
自動檢查也看不出來。usage 有兩條自動檢查:每次推上去跑的 CI,和發版時跑的流程。這兩條裡,沒有一步會執行 brew install。
但只要跑一次 brew install,就會看到那行錯。
打開你專案的 README,找到教人安裝的那一段,把指令一字不差複製到終端機跑。
已經裝過的,先移除再裝;不然它可能直接告訴你「已經裝好了」,你看到的是舊的那一份:
brew uninstall 套件名
npm uninstall -g 套件名
pip uninstall 套件名
這三行分別對應用 Homebrew、npm(全域安裝)、pip 裝的軟體,挑你 README 用的那一種。
跑完看最後幾行。出現 Error、ENOENT、not found 這類字,就是你的 #32。
工作單(交給 AI 的任務說明)裡那格「做完怎麼算對」,今天再加兩行(沒用過這張工作單,也可以直接把這兩行交給 AI,當作驗收要求):
做完怎麼算對:
- (Day 4、Day 8 到 Day 24 加的幾行)
- 動到安裝方式(安裝說明檔、打包格式、README 的安裝指令):照 README 一字不差跑一次安裝,貼出最後 10 行輸出
- 修使用者回報的錯誤:照他寫的步驟重跑一次,貼出這次成功的輸出,再回覆他「修好了」
README 裡那行安裝指令,每次發版都跟著出門。它需要的驗收,就是有人照著跑一次。
6 月 22 日,一位使用者點了面板裡的「reload」,整個面板變成一片空白。他想把 App 關掉重開,卻找不到結束的地方。明天看這一次。