DEV Community

Adrin T Paul
Adrin T Paul

Posted on

A user's terminal opened a code editor instead of running my CLI tool.

No error. No crash log. Just... my .js file, popped open in an IDE, like the computer decided to "take a look" instead of executing it.

Here's what actually happened.


*I built an MCP server — promptbuilder-mcp — so Claude Desktop and Cursor can pull prompt components straight from my vault. Published it to npm. Tested it. Worked perfectly on my machine.
*

Then a Windows user installed it globally and ran:

promptbuilder-mcp --key pb_xxxx

Their terminal printed a warning about "Electron/Chromium" not recognizing the --key flag. Then their code editor opened. Then nothing.

My first instinct: PATH conflict. Some other tool hijacking the command. I had them run Get-Command — clean, it pointed straight at my own npm shim. Not a conflict.

So I read the shim npm had generated for Windows:

& "$basedir/node_modules/promptbuilder-mcp/bin/promptbuilder-mcp.js" $args

*No node executable in that line. Just the .js file, called directly.
*

On Windows, .js files have no native way to execute themselves. There's no shebang interpretation at the OS level like on Linux/Mac. So when PowerShell hit a file it couldn't run, it fell back to whatever app Windows had associated with .js — which on that machine happened to be an Electron-based editor.

That explained everything. The "Electron/Chromium" warning. The editor opening. All of it.

*But why would npm generate a broken shim in the first place?
*

_npm's shim generator (cmd-shim) decides which template to use by checking for a shebang line at the top of your bin file — #!/usr/bin/env node. If it finds one, it builds a proper shim that calls node explicitly. If it doesn't, it falls back to the broken "just run the file" template.

I checked my bin file with a hex dump:

69 6D 70 6F 72 74 20 7B 20 73 → "import { s..."

No shebang. The file started directly with my import statement. I'd never added one — because on Mac and Linux, npm CLI tools often work fine without it, since those shells handle execution differently._

The fix was one line:

#!/usr/bin/env node
import { startServer } from "../src/index.js";

Republished. Reinstalled clean on Windows. The shim regenerated correctly. The server ran.


The part that stuck with me: this had been broken since the very first publish. Every Windows user who installed it globally hit this — silently, with no error pointing anywhere near the real cause. "It works on my machine" is true and also completely useless when your machine was never the one that mattered.

Cross-platform testing isn't a checkbox. It's the only way bugs like this surface before a real user finds them for you.

If you've shipped a CLI tool — have you tested the literal install path a stranger would take, on every OS you claim to support? Not the dev shortcut. The real one.

buildinpublic #mcp #softwareengineering #debugging #npm

Top comments (1)

Collapse
 
frank_signorini profile image
Frank

This often happens if the shebang `#!/usr/