Skip to content
Latchkey

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.

Ruby error
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.

Terminal
# 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
# Gemfile
gem 'mini_racer'   # bundles V8 as the ExecJS runtime

How 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.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →