Ruby execjs "Could not find a JavaScript runtime" in CI
A gem that uses ExecJS (often during asset precompilation) found no JavaScript engine on the runner. ExecJS shells out to Node or another runtime - when none is installed, it raises RuntimeUnavailable.
What this error means
A task such as assets:precompile fails with ExecJS::RuntimeUnavailable "Could not find a JavaScript runtime". The Ruby side is fine; there is simply no JS engine for ExecJS to drive.
ExecJS::RuntimeUnavailable: Could not find a JavaScript runtime.
See https://github.com/rails/execjs for a list of available runtimes.Common causes
No JavaScript engine on the runner
ExecJS needs an external runtime (Node.js is the usual choice). A slim image without Node, and without a JS-runtime gem like mini_racer, leaves ExecJS with nothing to use.
Node present but not on PATH
Node may be installed but not on the PATH visible to the build step, so ExecJS cannot detect it.
How to fix it
Install Node.js
A Node runtime on PATH is the simplest engine for ExecJS.
# Debian/Ubuntu
apt-get update && apt-get install -y nodejs
# or in GitHub Actions
- uses: actions/setup-node@v4
with:
node-version: '20'Or add a JS runtime gem
A bundled runtime gem removes the dependency on a system Node.
# Gemfile
gem 'mini_racer' # bundles V8 as the ExecJS runtimeHow to prevent it
- Provision Node.js in CI for any job that precompiles assets.
- Or bundle a JS-runtime gem so the runtime travels with the app.
- Confirm node is on PATH in the same step that runs ExecJS.