Lately I’ve been working in an Electron application to flash iso/img images to
drives in an easy way in all major operating systems based on the flashing
npm module we developed when working on the Resin CLI tool.
After spending literally all day (~8 hours) debugging a very weird issue, I want to write it down here, since its hilarious.
Given the nature of the Electron application, it requires administration permissions to be able to access raw devices directly. The application checks if the current user has such permissions and if not, prompt the user for the administrative password, and re-run the application. For this purpose we used two modules:
Each which provides such functionality for Windows and macOS/Linux respectively.
We also configured an
npm script, called
start to run the application. So
far so good.
Turns out that when running
npm start in macOS, we got the following error:
Command failed: /bin/sh -c sudo -n /Users/jviotti/Projects/resin/etcher/node_modules/electron-prebuilt/dist/Electron.app/Contents/MacOS/Electron lib/etcher.js env: node\r: No such file or directory
The carriage return symbol leads us to think the problem is caused by a Node.js
file containing a hashbang like
#!/usr/bin/env node encoded with Windows file
After searching the whole codebase and installed dependencies for files
relevant files containing such a hash bang, and running
dos2unix on them, the
What was even more confusing was that the following command ran without any issues from the terminal, correctly prompting for permissions and without any sign of the mysterious carriage return output.
sudo -n /Users/jviotti/Projects/resin/etcher/node_modules/electron-prebuilt/dist/Electron.app/Contents/MacOS/Electron lib/etcher.js
After trying to reproduce the issue with the smallest possible code surface
require blocks and basically simplifying the application to just
the code that performs the elevation), there was no sign of progress.
I created a tiny Electron application that reused
sudo-prompt with a similar
routine than our main application, and that worked fine as well.
The only difference I could spot was the installed dependencies. Not the
required ones, but the ones that actually lived in the
directory, which was key to solve the bug.
I started removing modules from
node_modules/ which were not used by the
slimmed down application, until bam! The issue was gone when removing
This made sense since it’s a Windows module and we can assume it was created in a Windows environment and contain carriage return line endings.
After doing a small search for
/usr/bin/env node, I stumbled into
windosu/bin/sudo, a Node.js script for when using the module globally.
dos2unix on it, re-run the application with
npm start, and nothing.
$ npm start > email@example.com start /Users/jviotti/Projects/resin/etcher > electron lib/etcher.js
The app didn’t even run, nor prompt me for my password. But clearly something
changed when converting
windosu/bin/sudo to UNIX line endings, so for some
reason, this script was being called.
sudo-prompt code, we can see it runs
sudo with the
which means “non-interactive” as a smart way to check the permissions of the
Turns out that binary files specificed as
bin in the
node_modules/.bin when installed locally, and this directory gets
added to the
PATH when executing an
Since the binary that
windosu exposes is called
sudo, it shadowed
sudo-prompt was unintentially calling
of the real
sudo, leading to well, nothing good.
The 8 hours worth fix consisted in 6 characters: calling
sudo-prompt, and all back to normal!