I Crashed a Rust Formatter on My Android Phone — A Maintainer Fixed It Before Lunch 💥
If you do dev work inside Termux on Android, you already know the platform loves to surface bugs that desktop Linux and macOS builds never trigger. This is the story of how I broke oxfmt — the formatter from the oxc toolchain — on my aarch64 phone, filed it upstream, and watched it get fixed in a matter of hours.
The Setup
I was running oxfmt v0.63.0 straight from Termux to format a TypeScript file. Simple, routine, the kind of thing that should just work.
It didn't.
The Crash
Every single invocation, no matter the file, ended the same way — an instant panic followed by a native SIGABRT:
thread 'main' (9632) panicked at apps/oxfmt/src/cli/walk_runner.rs:116:18:
External services must be set when `napi` feature is enabled
logcat backed it up with a real tombstone, not just a caught panic:
F libc : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 9632 (oxfmt), pid 9632 (oxfmt)
F DEBUG : Abort message: 'External services must be set when `napi` feature is enabled'
The message gave the game away: this build of oxfmt had been compiled with the napi (Node native-addon) Cargo feature turned on, which expects some external host to register a service before the binary runs. Standalone in Termux, that host never shows up — so the check at walk_runner.rs:116 fails and the whole process aborts. Every time. On every file.
Filing the Bug
I wrote it all up — repro steps, full system info, logcat, and the crash log — and opened termux/termux-packages#30954.
Within a few hours, @robertkirkman — one of the termux-packages maintainers — picked it up:
"I think that I know what is wrong and I will try to fix it but I don't know whether I can yet"
Not long after, he came back with a test build compiled with the napi feature disabled, and a nightly.link artifact to try it on-device.
Confirmed Fixed
I installed the test .deb on my phone, pointed it at the same file that had been aborting all day, and — it just formatted it. No panic, no SIGABRT, nothing. I reported back on the issue that it was fully resolved, and @robertkirkman merged the fix as termux/termux-packages#30955, which disables the napi feature for the Termux build of oxfmt.
From first report to merged fix: less than a day. That's open source at its best.
The Catch: napi Support Is Still an Open Question
This fix is explicitly a workaround, not a real solution. As @robertkirkman put it when merging:
"I don't know how to fix the
napifeature so I had to try disabling thenapifeature... I will merge it now as a temporary measure until in the future if someone needs thenapifeature for additional functionality, they can open a separate issue to request that I guess"
So right now, oxfmt on Termux works — but only because the napi integration is switched off entirely. Nobody has yet figured out what "External services" oxfmt expects the napi feature to provide on Android, or how to properly wire that up in a standalone-CLI build.
If you know your way around Rust, N-API, or the oxc codebase, this is a great place to jump in. A proper fix would mean oxfmt on Android doesn't have to permanently give up whatever functionality napi was meant to unlock.
Good places to start:
- The original crash report:
termux/termux-packages#30954 - The temporary workaround PR:
termux/termux-packages#30955 - The upstream project:
oxc-project/oxc - The termux-packages repo, if you want to help maintain the Android build itself
Even if you're not a Rust person, testing, triaging, and reporting edge cases like this one is exactly how bugs like this get caught in the first place.
Thanks for reading — and if you end up picking up the napi issue, tag me, I'd love to test it. 🚀
Top comments (0)