Node "bad interpreter" - Fix CRLF Shebang in a bin Script in CI
A shebang line with Windows CRLF endings makes the kernel read the interpreter as node\r (node plus a carriage return). On Linux CI that interpreter does not exist, so the script fails with a confusing "bad interpreter" / "No such file or directory" - even though node is installed.
What this error means
Executing a bin script fails with /usr/bin/env: ‘node\r’: No such file or directory (or bad interpreter). It typically appears after a file was authored or checked out with CRLF endings and then run on Linux.
$ ./scripts/build.js
/usr/bin/env: 'node\r': No such file or directory
# the shebang line ends with \r\n, so the interpreter is "node\r"Common causes
CRLF line endings on the shebang line
A file saved with Windows CRLF carries a trailing \r on the shebang. The loader treats node\r as the interpreter name, which does not exist on Linux.
Git re-introducing CRLF on checkout
A misconfigured core.autocrlf or a .gitattributes gap can check out script files with CRLF in CI even if they are LF in the repo.
How to fix it
Convert the script to LF endings
Strip the carriage returns and keep the file LF-only.
# fix the file
sed -i 's/\r$//' scripts/build.js
# enforce LF for scripts via .gitattributes
echo '*.js text eol=lf' >> .gitattributes
echo 'bin/* text eol=lf' >> .gitattributesStop CRLF at the source
- Set
.gitattributesto force LF for shell/JS bin scripts. - Configure editors to save scripts as LF.
- Avoid
core.autocrlf=truefor files that must stay LF.
How to prevent it
- Force LF for executable scripts via .gitattributes.
- Save bin scripts with LF endings.
- Keep shebang lines free of trailing carriage returns.