facebook/relay · critical

failed to execute process. Make sure you have Node installed

Error message

failed to execute process. Make sure you have Node installed.

What it means

js-config-loader executes the project's relay.config.js (an ESM module) by spawning the `node` binary with --input-type=module and importing the file's default export. If the `node` executable cannot be spawned at all, Command::output() returns Err and .expect() panics with this message.

Source

Thrown at compiler/crates/js-config-loader/src/loader.rs:80

pub struct JsLoader;
impl<T: for<'de> Deserialize<'de> + 'static> Loader<T> for JsLoader {
    fn load(&self, path: &Path) -> Result<Option<T>, ErrorCode> {
        // Convert Windows paths to valid ECMAScript module specifiers
        #[cfg(target_os = "windows")]
        let path = (if path.is_absolute() {
            format!("file://{}", path.to_string_lossy())
        } else {
            path.to_string_lossy().into_owned()
        })
        .replace('\\', "/");

        let output = Command::new("node")
            .arg("--input-type=module")
            .arg("-e")
            .arg(r#"process.stdout.write(JSON.stringify((await import(process.argv[1])).default))"#)
            .arg(path)
            .output()
            .expect("failed to execute process. Make sure you have Node installed.");

        if output.status.success() {
            let value = serde_json::from_slice::<T>(&output.stdout);
            Ok(Some(value.unwrap()))
        } else {
            Err(ErrorCode::NodeExecuteError { output })
        }
    }
}

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Install Node.js or ensure a node binary is on PATH (`which node`)
  2. Activate the correct nvm/volta version in the shell before running relay
  3. Set PATH explicitly in CI/Docker (e.g. ENV PATH=/usr/local/node/bin:$PATH)
  4. If node exists but the script itself fails, inspect the NodeExecuteError output instead — this panic is only for spawn failure

Example fix

// before (shell)
relay build   // no node on PATH -> panic
// after
export PATH="$HOME/.nvm/versions/node/v20.11.0/bin:$PATH"
relay build
Defensive patterns

Strategy: validation

Validate before calling

import { execFileSync } from 'child_process';
function assertNodeAvailable() {
  try { execFileSync('node', ['--version'], { stdio: 'ignore' }); }
  catch { throw new Error('Node.js must be installed and on PATH'); }
}

Try / catch

try {
  loadJsConfig(path);
} catch (e) {
  if (/failed to execute process/.test(e.message)) {
    console.error('Install Node.js and ensure `node` is on PATH.');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the js-config loader's `load` when `node` is not on PATH, Node.js is not installed, or the process lacks permission to execute it.

Common situations: Fresh Docker/CI images without Node installed; nvm-managed Node not on PATH in the invoking shell; running the relay binary from an environment (GUI launcher, systemd service) with a minimal PATH.

Related errors


AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02). Data as JSON: /api/errors/ec0d76000bb67058. Report an issue: GitHub.