{"record":{"id":"ec0d76000bb67058","repo":"facebook/relay","slug":"failed-to-execute-process-make-sure-you-have-node","errorCode":null,"errorMessage":"failed to execute process. Make sure you have Node installed.","messagePattern":"failed to execute process\\. Make sure you have Node installed\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/crates/js-config-loader/src/loader.rs","lineNumber":80,"sourceCode":"pub struct JsLoader;\nimpl<T: for<'de> Deserialize<'de> + 'static> Loader<T> for JsLoader {\n    fn load(&self, path: &Path) -> Result<Option<T>, ErrorCode> {\n        // Convert Windows paths to valid ECMAScript module specifiers\n        #[cfg(target_os = \"windows\")]\n        let path = (if path.is_absolute() {\n            format!(\"file://{}\", path.to_string_lossy())\n        } else {\n            path.to_string_lossy().into_owned()\n        })\n        .replace('\\\\', \"/\");\n\n        let output = Command::new(\"node\")\n            .arg(\"--input-type=module\")\n            .arg(\"-e\")\n            .arg(r#\"process.stdout.write(JSON.stringify((await import(process.argv[1])).default))\"#)\n            .arg(path)\n            .output()\n            .expect(\"failed to execute process. Make sure you have Node installed.\");\n\n        if output.status.success() {\n            let value = serde_json::from_slice::<T>(&output.stdout);\n            Ok(Some(value.unwrap()))\n        } else {\n            Err(ErrorCode::NodeExecuteError { output })\n        }\n    }\n}\n","sourceCodeStart":62,"sourceCodeEnd":90,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/compiler/crates/js-config-loader/src/loader.rs#L62-L90","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Install Node.js or ensure a node binary is on PATH (`which node`)","Activate the correct nvm/volta version in the shell before running relay","Set PATH explicitly in CI/Docker (e.g. ENV PATH=/usr/local/node/bin:$PATH)","If node exists but the script itself fails, inspect the NodeExecuteError output instead — this panic is only for spawn failure"],"exampleFix":"// before (shell)\nrelay build   // no node on PATH -> panic\n// after\nexport PATH=\"$HOME/.nvm/versions/node/v20.11.0/bin:$PATH\"\nrelay build","handlingStrategy":"validation","validationCode":"import { execFileSync } from 'child_process';\nfunction assertNodeAvailable() {\n  try { execFileSync('node', ['--version'], { stdio: 'ignore' }); }\n  catch { throw new Error('Node.js must be installed and on PATH'); }\n}","typeGuard":null,"tryCatchPattern":"try {\n  loadJsConfig(path);\n} catch (e) {\n  if (/failed to execute process/.test(e.message)) {\n    console.error('Install Node.js and ensure `node` is on PATH.');\n  } else throw e;\n}","preventionTips":["Verify `which node` succeeds in the environment running relay","Bake Node into Docker/CI base images","Keep nvm/volta versions activated in shells and IDE terminals","Avoid deleting/renaming the node binary under package managers"],"tags":["nodejs","environment","path","process-spawn"],"backgroundTag":"missing-node-path","analyzedSha":"668b1b85e06261aa3b58dabfc51f8b5524a70955","analyzedAt":"2026-09-02T19:57:20.783Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}