BuildNot yet confirmed elsewhere1 publisher2 min readPublished
167 of 1,383 public Claude Code mods break on Windows by calling Unix-only tools
A review of 1,383 public Claude Code mods found that 167 break on Windows because they call Unix tools like tail and open through $.process.run. The call uses no shell, so a tool Windows does not ship rejects on launch.
The Engineer · Build desk

What happened
- Because $.process.run launches a program directly with no shell, cmd built-ins such as start and dir are not executables and cannot be launched either.
- A failed launch or a 30-second timeout rejects the call, while a non-zero exit code resolves as a normal result.
- Many of the flagged mods still carried their original Mac tool names unchanged in the code.
- The review covered Claude Code versions 2.1.284 to 2.1.288, tested on Windows 11 in October 2026.
- On Windows, $.audio.play plays no sound and throws no error, so an audio failure never reaches the mod's own .catch handler.
Why it matters
- constraint Any mod that leans on tail, open, osascript, afplay or xdg-open has no Windows path short of rewriting it to the mods API or branching on the operating system.
- cost A mod tested only on a Mac ships to Windows users with broken audio and no error in its own handling to reveal it, because the call reports success while playing nothing.
- decision An unhandled rejection from a missing command crashes the whole hook, so authors have to wrap every $.process.run in try/catch or stop shelling out.
- exposure The Start-Process workaround becomes an injection surface the moment a file path is concatenated into the command string instead of passed as an environment variable.
The practical response comes in a fix order, and the first recommendation is to stop calling the operating system at all. "The best fix is to not launch an external program at all and use the mods API instead," nakadadev wrote [9]. The mods API abstracts the platform, so code that uses it does not need to know which OS it runs on [10]. That only helps where the API has an equivalent for whatever the mod was launching externally. The 167 count is a snapshot from 2026-10-06, and it is 12 percent of the 1,383 mods reviewed [1][19].
Not every external command is a problem. Programs that ship a same-named executable on Windows, such as git and gh, run unchanged as long as they are on PATH [11]. The call wants an array of arguments, so a single string like `'git status'` fails and has to be split into array elements [14]. The gray area is `.cmd` wrappers like npm and npx: whether they launch directly without a shell is not documented, so the author treats it as unverified and falls back to `['cmd.exe', '/c', 'npm', ...]` when the direct call does not work [20].
Branching per OS is harder than it sounds, because a hook has no `process` object and cannot read `process.platform` [12]. The author identifies Windows from the shape of `$.plugin.root`, treating a path that starts with a drive letter as Windows [12]. For opening a file, the Windows branch runs PowerShell's `Start-Process` in place of Mac's `open`, and passes the file path through an environment variable so a space or a single quote in the path cannot break the command [13].
Sound is the failure that hides best. The core plays audio only through `globalThis.Audio` or macOS `afplay`; on Windows it writes "no audio player on windows; not played" to the debug log and resolves as a success [18]. The same executable runs behind the desktop app's Code tab, so audio is silent there too [16]. The Windows workaround runs PowerShell again, playing a PCM WAV through `System.Media.SoundPlayer`, which cannot play MP3, takes about a second to start, offers no volume control, and forces the author to drop any sound that arrives while one is still playing so the processes do not pile up [17].
What to watch
- Whether Anthropic adds a cross-platform audio path so $.audio.play stops silently succeeding on Windows.
- Whether the mods API gains native equivalents for the Unix tools authors currently launch externally.
- Whether a documented answer appears on launching .cmd wrappers like npm and npx without a shell.
Clarity's read
What the record supports and how the coverage leans. The claims behind it follow.
Reality
- Evidence50
- Adoption
- Insufficient
- Hype gap+5
- Incentives
- Insufficient
- Confidence48
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
A review read 1,383 public Claude Code mods on GitHub and found 167 that use $.process to launch a program Windows does not have, as of 2026-10-06, roughly 1 in 8.
- [2]
Most mods written on Mac or Linux break on Windows because they use $.process to launch programs Windows does not have, such as tail, date, open, osascript, afplay and xdg-open.
- [3]
The official API page says $.process.run takes an array of arguments and does not use a shell.
- [4]
Because $.process.run does not go through a shell, cmd built-ins like start and dir are not executables and cannot be launched.
- [5]
$.process.run rejects when the program cannot start and when it times out, 30 seconds by default; a non-zero exit code still resolves.
- [6]
If the call is not wrapped in try/catch, the throw takes the whole hook down with it.
- [7]
Versions checked were Claude Code 2.1.284 to 2.1.288, in October 2026 on Windows 11.
- [8]
Many of the flagged mods still had Mac tool names left in them as-is.
- [9]
The best fix is to not launch an external program at all and use the mods API instead.
- [11]
Programs that ship an executable with the same name on Windows, like git and gh, work as-is as long as they are on the PATH.
- [12]
There is no process object inside a hook, so process.platform cannot be used; the author detects Windows by whether $.plugin.root starts with a drive letter.
- [13]
Instead of Mac's open, the Windows path launches PowerShell's Start-Process and passes the file path through an environment variable, because a single quote or space in the path breaks the command and opens the door to injection.
- [14]
A single string like 'git status' fails; the API wants an array of arguments instead.
- [15]
On Windows $.audio.play plays nothing, throws nothing, and never reaches .catch.
- [16]
The Code tab in the desktop app runs the same executable, so sound is silent there too.
- [17]
The Windows audio workaround uses PowerShell with System.Media.SoundPlayer to play a PCM WAV; it cannot play MP3, startup takes about one second, there is no volume control, and sounds that arrive while one is playing are dropped so processes do not pile up.
- [18]
The core plays sound only through globalThis.Audio or macOS afplay; on Windows it writes "no audio player on windows; not played" to the debug log and resolves as a success.
- [19]
167 of the 1,383 reviewed mods is 12 percent, about one in eight.
- [20]
For commands installed as .cmd files on Windows, like npm and npx, whether they can be launched directly without a shell is not documented, so it is unverified; if it fails, launch explicitly with ['cmd.exe', '/c', 'npm', ...].
Sources
1 independent publisher whose own reporting we read for this story.
Topics and entities
Follow any of these and your For You feed starts watching them — no settings page required.