Someone filed a bug and it made my week
The first outside user, a crash on Apple Silicon, and what it taught me about building in the open.
@jamditis
Two months into building AudioBash, I got a GitHub notification that stopped me mid-sentence.
Issue #29: "App crashes on launch (Apple Silicon)"
Someone had downloaded AudioBash. Someone who wasn't me. They'd installed it on their Mac, tried to open it, and it crashed immediately. Then they took the time to file an issue about it.
I know that sounds like a bad thing. It wasn't. It was the best notification I'd gotten since starting this project.
Why a bug report felt like a gift
When you're building something alone, for yourself, you exist in a bubble. You know the app works on your machine. You know it works the way you use it. But you have no idea if anyone else cares, or if the thing even runs outside your specific setup.
A bug report means someone cared enough to try. And then cared enough to tell you it was broken instead of just closing the tab and moving on.
Most people who hit a crash on launch would never come back. This person opened an issue. That's a small act, but it meant everything to a solo developer with zero users.
The bug
The crash was silent. No error dialog, no crash report — the app just didn't open. On an M1 Mac, double-click the .dmg, drag to Applications, launch. Nothing.
I'd built macOS support back in January and tested it on my own M1 MacBook Pro. It worked. So what changed?
The difference was how the app got to the machine. When you build an Electron app locally with npm run electron:build, the resulting binary isn't quarantined. macOS trusts it because you built it yourself. But when someone downloads a .dmg from GitHub Releases, macOS marks it with a quarantine flag. And quarantined apps on Apple Silicon face stricter checks.
Specifically: code signature validation.
The root cause
AudioBash uses node-pty to spawn shell processes. It's a native module — compiled C++ code that interfaces with the operating system's terminal subsystem. On macOS, native binaries have code signatures. Apple Silicon (ARM64) enforces these signatures more strictly than Intel.
Here's what was happening:
During the build process, I had an afterPack script that ran chmod on the node-pty binaries to make sure they had the right permissions. Standard stuff. But on ARM64, running chmod on a signed binary invalidates its code signature.
The binary was fine. The permissions were fine. But the signature was broken, and macOS refused to load it.
# The problem: chmod invalidates ARM64 code signatures
chmod 755 node_modules/node-pty/build/Release/pty.node
# ^ This breaks the signature on Apple Silicon
# The fix: re-sign after chmod
chmod 755 node_modules/node-pty/build/Release/pty.node
codesign --force --sign - node_modules/node-pty/build/Release/pty.node
# ^ Ad-hoc signing restores the signature
That's it. One line. codesign --force --sign - after the chmod. Ad-hoc signing (the - means "sign with no identity") is enough for macOS to accept the binary from a quarantined app.
The second problem
While digging into the crash, I found a second issue. The app's app.whenReady() handler — the function that runs when Electron finishes starting up — had no error handling. If anything threw during initialization, the app died silently. No log. No dialog. Just gone.
I added a try-catch around the initialization, a global error handler for uncaught exceptions, and a guard around the tray icon creation (which was trying to access a window that didn't exist yet if the main window failed to create).
None of these were exotic fixes. They're the kind of defensive code you'd expect in any production app. I just hadn't written them because the app had never crashed on me.
Shipping the fix
I pushed v2.4.0 the same day. The fix was two changes:
- Re-sign node-pty binaries after
chmodin the afterPack script - Add error handling to the app initialization path
I also upgraded Electron from 35 to 39, which fixed a separate GPU rendering lag on macOS Tahoe. And I hardened the transcription pipeline with rate limiting and input validation, since I was already in there fixing things.
The whole cycle — from issue filed to fix released — was less than a day.
When you're a solo dev, you can ship a fix the same day someone reports a bug. No sprint planning. No ticket queue. No waiting for the next release train. Someone says "this is broken," and you fix it. That feedback loop is addictive.
What I learned
Build from source works, downloads might not
This is specific to macOS and Electron, but worth knowing: an app that runs perfectly when built locally can crash when downloaded. The quarantine flag changes the security context. If you distribute unsigned macOS apps, you need to test the actual download path, not just the build output.
Native modules are a minefield on Apple Silicon
ARM64 enforces code signatures at the kernel level. Any post-build step that modifies a binary — chmod, strip, patching — will break the signature. You have to re-sign. This isn't well-documented, and it took hours of research to piece together.
Silent crashes are the worst crashes
An app that shows an error message is better than an app that does nothing. Users can report an error. They can't report "I double-clicked and nothing happened." Add global error handlers. Log to a file. Show a dialog. Do something.
The first user matters more than the first feature
Before issue #29, AudioBash had 30 releases, 721 tests, cross-platform support, and five transcription providers. None of that mattered until someone other than me tried to use it. The real test of software isn't whether it passes your test suite. It's whether it runs on someone else's machine.
Building in the open
I could have built AudioBash as a private project forever. I almost did. It's a personal tool — I built it because I needed it, and I'd use it regardless of whether anyone else does.
But putting it on GitHub and making releases public created this feedback loop that I didn't expect. One bug report from one user taught me more about macOS code signing than weeks of reading documentation. And fixing that bug made the app better for everyone who tries it next.
The app is at github.com/jamditis/audiobash. If you're on a Mac (or Windows) and use voice with your terminal, try it out. And if it crashes, please file an issue. I mean that.